Back to skill

Security audit

预测市场套利

Security checks for vulnerabilities and agentic risk

Overview

The skill is read-only and purpose-adjacent, but it exposes under-documented wallet analytics that can send wallet addresses and financial-profile queries to AIsa, so it belongs in Review.

Install only if you are comfortable giving this skill an AIsa API key and allowing it to make paid, authenticated requests to api.aisa.one. Avoid using the wallet activity, wallet, positions, orders --user, or P&L commands unless you intentionally want those wallet identifiers and analytics requests sent to AIsa. The artifact does not execute trades or access private keys, but its wallet-query capability is broader than the SKILL.md disclosure.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/arbitrage_finder.py:54
Finding

Bearer API credential may be disclosed through unrestricted HTTP redirects

Content
View full analysis
Dict[str, Any]: url = f"{self.BASE_URL}{path}" if params: qs = urllib.parse.urlencode({k: v for k, v in params.items() if v is not None}) if qs: url = f"{url}?{qs}" headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", "User-Agent": "OpenClaw-ArbitrageFinder/1.0", } req = urllib.request.Request(url, headers=headers, method="GET") try: with urllib.request.urlopen(req, timeout=60) as resp: return json.loads(resp.read().decode("utf-8")) except urllib.error.HTTPError as e: body = e.read().decode("utf-8") try: return json.loads(body) except json.JSONDecodeError: return {"error": {"code": str(e.code), "message": body}} except urllib.error.URLError as e: return {"error": {"code": "NETWORK_ERROR", "message": str(e.reason)}} def _get_multi(self, path: str, params_list: List[Tuple[str, str]]) -> Dict[str, Any]: """GET with repeated query params (e.g. multiple slugs/tickers).""" qs = "&".join(f"{urllib.parse.quote(k)}={urllib.parse.quote(v)}" for k, v in params_list) url = f"{self.BASE_URL}{path}?{qs}" if qs else f"{self.BASE_URL}{path}" headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", "User-Agent": "OpenClaw-ArbitrageFinder/1.0", } req = urllib.request.Request(url, headers=headers, method="GET") try: with urllib.request.urlopen(req, timeout=60) as resp: ret ...[truncated 2562 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/prediction_market_client.py:142
Finding

Undeclared wallet analytics exceed the minimum capability required for arbitrage discovery

Content
View full analysis
Dict[str, Any]: """Get activity for a Polymarket wallet address.""" return self._request("/polymarket/activity", params={ "user": user, "market_slug": market_slug, "condition_id": condition_id, "start_time": start_time, "end_time": end_time, "limit": limit, "offset": offset, }) def polymarket_orders(self, market_slug: Optional[str] = None, condition_id: Optional[str] = None, token_id: Optional[str] = None, user: Optional[str] = None, start_time: Optional[int] = None, end_time: Optional[int] = None, limit: int = 100, offset: int = 0) -> Dict[str, Any]: """Get Polymarket trade history.""" return self._request("/polymarket/orders", params={ "market_slug": market_slug, "condition_id": condition_id, "token_id": token_id, "user": user, "start_time": start_time, "end_time": end_time, "limit": limit, "offset": offset, }) def polymarket_positions(self, wallet_address: str, limit: int = 100, pagination_key: Optional[str] = None) -> Dict[str, Any]: """Get Polymarket positions for a proxy wallet.""" return self._request(f"/polymarket/positions/wallet/{wallet_address}", params={ "limit": limit, "pagination_key": pagination_key, }) def polymarket_wallet(self, eoa: Optio ...[truncated 4118 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose is a read-only arbitrage finder, but the analysis indicates broader wallet and user-level data access plus a generic market data client that exceeds the stated scope. This mismatch is dangerous because users or agents may grant API keys and run commands under the assumption of limited functionality, while the underlying skill could access sensitive account-related information or perform undeclared data collection.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares environment-variable and network-dependent behavior but does not define any explicit tool scope such as permissions or allowed-tools. That makes the trust boundary unclear for an agent runtime and can permit broader-than-expected execution or outbound access, especially since the skill instructs use of an API key and remote HTTP requests.

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 · scripts/arbitrage_finder.py (reported line 43)May include surrounding context.

python
class AIsaClient:
    """Lightweight client for the AIsa prediction market API."""

    BASE_URL = "https://api.aisa.one/apis/v1"

    def __init__(self, api_key: Optional[str] = None):
        self.api_key = api_key or os.environ.get("AISA_API_KEY")

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 · scripts/prediction_market_client.py (reported line 52)May include surrounding context.

python
class AIsaClient:
    """Lightweight client for the AIsa prediction market API."""

    BASE_URL = "https://api.aisa.one/apis/v1"

    def __init__(self, api_key: Optional[str] = None):
        self.api_key = api_key or os.environ.get("AISA_API_KEY")

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The implementation supports broad Polymarket and Kalshi market/trade retrieval across domains, while the manifest describes a narrower sports arbitrage scanner. This mismatch increases the chance the skill is used for broader market intelligence collection than users expect, weakening least-privilege and informed-consent boundaries.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill exposes wallet activity, positions, wallet metadata, and P&L lookups that go beyond the stated purpose of cross-platform sports arbitrage scanning. Even if the underlying data is public or semi-public, bundling these surveillance-oriented capabilities into an arbitrage skill creates an unnecessary privacy and scope-expansion risk and enables user profiling unrelated to the manifest.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The wallet-focused functions allow querying activity, positions, wallet metadata, and realized P&L for arbitrary addresses, which is not necessary to identify price discrepancies between platforms. In this context, they create a surveillance capability that can be used to track trading behavior and financially profile third parties.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Wallet addresses supplied to the activity endpoints are transmitted to an external API without any user-facing notice in the code path. That omission can mislead users about privacy implications and results in silent disclosure of wallet-linked behavioral data to a third party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The client reads the AISA_API_KEY from the environment and uses it in outbound Authorization headers for every request. Although this is functionally necessary, the code does not include a clear user-facing warning or disclosure that credentials from the local environment will be accessed and sent to an external service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.