Back to skill

Security audit

Polymarket Spread Arbitrage

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a disclosed read-only prediction-market API tool, but it needs review because it includes wallet/P&L lookups beyond the core arbitrage purpose and handles an API key without redirect safeguards.

Review this before installing if wallet privacy or API-key exposure matters in your environment. Use a scoped, low-credit AIsa API key, avoid querying wallets you are not authorized to analyze, and consider hardening or wrapping the Python clients so Authorization headers are never sent after cross-origin redirects.

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

T09 · Insecure Skill Coding Practices

Warning
Location
script/prediction_market_client.py:75
Finding

Bearer API Key May Be Disclosed Through Automatic Redirects in the Prediction Market Client

Content
View full analysis

Vulnerability Details

File Location: script/prediction_market_client.py, lines 75-83
Vulnerability Type: Authorization credential exposure through automatic cross-origin redirects
Risk Level: Medium

Vulnerable Code

python
headers = {
    "Authorization": f"Bearer {self.api_key}",
    "Content-Type": "application/json",
    "User-Agent": "OpenClaw-PredictionMarket/1.0",
}

req = urllib.request.Request(url, headers=headers, method="GET")

try:
    with urllib.request.urlopen(req, timeout=60) as response:
        return json.loads(response.read().decode("utf-8"))

Technical Analysis

The client attaches the AIsa API key to an Authorization: Bearer header and passes the request to urllib.request.urlopen. Python's standard URL opener follows HTTP redirects by default. The implementation does not install a restrictive redirect handler, validate the destination origin after a redirect, or remove the authorization header when the origin changes.

Consequently, a compromised or misconfigured api.aisa.one endpoint could return a redirect to an attacker-controlled host. The redirected request may disclose the bearer credential to that host. TLS protects the request in transit but does not protect a credential intentionally forwarded to a different HTTPS destination.

Sending the API key to the documented AIsa API is necessary for the Skill's authenticated functionality. Allowing that credential to follow redirects to an arbitrary origin is not necessary and exceeds minimum required credential exposure.

Attack Path

  1. A user configures a valid AISA_API_KEY and invokes a client operation.
  2. The client sends an authenticated request to https://api.aisa.one.
  3. The API endpoint, or infrastructure controlling its response, returns an HTTP redirect to an attacker-controlled URL.
  4. The default redirect handler follows the redirect without enforcing an exact-origin policy.
  5. The bearer authorization header is transmitted to the ...[truncated 697 chars]
Remediation
View remediation

Remediation Suggestions

  • Disable redirects for authenticated API requests unless they are explicitly required.
  • If redirects are required, implement a custom HTTPRedirectHandler that permits only the exact expected HTTPS scheme, hostname, and port.
  • Remove the Authorization header whenever the destination origin differs from the original origin.
  • Reject HTTPS-to-HTTP redirects unconditionally.
  • Apply a small maximum redirect count and fail closed on malformed or unexpected Location values.
  • Centralize request and redirect validation so every authenticated method receives the same protection.
  • Add tests that simulate same-origin, cross-origin, and HTTPS-to-HTTP redirects and verify that credentials are never sent to an unauthorized destination.

T09 · Insecure Skill Coding Practices

Warning
Location
script/prediction_market_client.py:301
Finding

Bearer API Key May Be Disclosed Through Automatic Redirects in Raw GET Requests

Content
View full analysis

Vulnerability Details

File Location: script/prediction_market_client.py, lines 301-307
Vulnerability Type: Authorization credential exposure through automatic cross-origin redirects
Risk Level: Medium

Vulnerable Code

python
headers = {
    "Authorization": f"Bearer {self.api_key}",
    "Content-Type": "application/json",
    "User-Agent": "OpenClaw-PredictionMarket/1.0",
}
req = urllib.request.Request(url, headers=headers, method="GET")
try:
    with urllib.request.urlopen(req, timeout=60) as response:
        return json.loads(response.read().decode("utf-8"))

Technical Analysis

The _raw_get implementation sends the bearer API key through urllib.request.urlopen, which follows redirects by default. No redirect policy constrains the destination to https://api.aisa.one, and no logic strips the authorization header on an origin change.

The URL passed to _raw_get is constructed internally from the fixed base URL and encoded query parameters, so direct user-controlled host injection was not identified. Nevertheless, an HTTP redirect supplied by the API server can change the destination after the initial safe URL has been constructed.

Attack Path

  1. The user invokes a method that uses _raw_get, such as a market search or sports-market matching request.
  2. The client constructs a URL under the fixed https://api.aisa.one/apis/v1 base.
  3. The trusted endpoint returns a redirect to an attacker-controlled origin.
  4. The standard redirect handler follows that response.
  5. The redirected request carries the bearer credential to the attacker-controlled server.
  6. The attacker reuses the captured key for authenticated and potentially billable API requests.

Impact Assessment

Successful exploitation exposes the AIsa bearer key. This can enable unauthorized requests, consumption of account credits, and access to API data authorized for the key. The affected code is read-only and provides no direct operating-system privi ...[truncated 55 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace the default opener with an opener that rejects redirects or validates every redirect target.
  • Restrict authenticated requests to the exact https://api.aisa.one origin.
  • Never copy Authorization to a redirected request whose scheme, hostname, or port changes.
  • Reject protocol downgrades and non-HTTPS destinations.
  • Refactor _request and _raw_get to use one hardened request implementation rather than duplicating security-sensitive networking logic.
  • Add automated regression tests confirming that cross-origin redirect destinations receive no authorization header.

T09 · Insecure Skill Coding Practices

Warning
Location
script/arbitrage_finder.py:61
Finding

Bearer API Key May Be Disclosed Through Automatic Redirects in the Arbitrage Finder

Content
View full analysis

Vulnerability Details

File Location: script/arbitrage_finder.py, lines 61-68
Vulnerability Type: Authorization credential exposure through automatic cross-origin redirects
Risk Level: Medium

Vulnerable Code

python
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"))

Technical Analysis

The arbitrage client retrieves AISA_API_KEY and includes it in every API request. Its _get method relies on the default urllib.request opener, which follows redirects. The method does not verify that a redirect remains on the original API origin and does not remove authentication data when the destination changes.

Authenticated network access is necessary to retrieve matching markets, prices, and orderbooks. Cross-origin forwarding of the credential is not required for those capabilities.

Attack Path

  1. A user runs the arbitrage scanner with a valid AIsa API key.
  2. The scanner requests matching-market, price, or orderbook data from https://api.aisa.one.
  3. A compromised or misconfigured endpoint responds with a redirect to an attacker-controlled server.
  4. The client follows the redirect automatically.
  5. The authorization header reaches the redirected server.
  6. The attacker extracts and reuses the key.

Impact Assessment

The exposed key may allow unauthorized use of paid API operations and access to data available under the victim's AIsa account. The impact is limited to the API key's server-side permissions. No local persistence, SSH operations, code execution, or system-level privilege escalation was identified.

Remediation
View remediation

Remediation Suggestions

  • Reject redirects by default for API requests carrying bearer credentials.
  • If redirects are operationally required, allow only redirects that preserve the exact HTTPS origin.
  • Construct a fresh redirected request and omit Authorization whenever the origin changes.
  • Enforce HTTPS and reject redirects to IP literals, unapproved ports, or unapproved hostnames.
  • Document the expected redirect behavior and add security tests using a local redirecting test server.
  • Rotate the API key if logs or monitoring indicate that authenticated requests have previously followed unexpected redirects.

T09 · Insecure Skill Coding Practices

Warning
Location
script/arbitrage_finder.py:85
Finding

Bearer API Key May Be Disclosed Through Automatic Redirects in Multi-Parameter Requests

Content
View full analysis

Vulnerability Details

File Location: script/arbitrage_finder.py, lines 85-92
Vulnerability Type: Authorization credential exposure through automatic cross-origin redirects
Risk Level: Medium

Vulnerable Code

python
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"))

Technical Analysis

The _get_multi request path duplicates the unsafe authenticated networking behavior in _get. Although query parameter names and values are percent-encoded and the initial host is fixed, automatic redirect processing can still transfer the request to another origin after URL construction.

There is no destination allowlist, redirect limit defined by the application, protocol-downgrade check, or authorization-header removal policy.

Attack Path

  1. A user runs a slug- or ticker-based market match.
  2. _get_multi sends an authenticated request to the fixed AIsa API URL.
  3. The endpoint returns a cross-origin HTTP redirect.
  4. The default opener follows the redirect.
  5. The attacker-controlled destination receives the bearer API key.
  6. The attacker uses the key for unauthorized API access and credit consumption.

Impact Assessment

Exploitation compromises the confidentiality of the AIsa API key and can enable account-scoped API misuse. It does not grant direct access to local files, environment variables other than the already loaded key, system permissions, or trade execution.

Remediation
View remediation

Remediation Suggestions

  • Consolidate _get and _get_multi behind one hardened HTTP transport layer.
  • Disable automatic redirects or validate each redirect against an exact-origin allowlist.
  • Strip bearer credentials before any cross-origin redirected request.
  • Reject redirects that change the protocol, hostname, or port.
  • Preserve the existing percent-encoding of repeated parameters, but do not treat encoding as protection against server-directed redirects.
  • Add tests proving that authenticated headers remain available for approved same-origin requests but are absent from every rejected or cross-origin redirect.
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 (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description says the skill finds and analyzes arbitrage opportunities across prediction markets. However, the supplied code does not implement arbitrage detection, comparison logic, spread calculations, or any analysis workflow that identifies opportunities. Instead, it is a broad data retrieval client for the AIsa API, exposing many endpoints for Polymarket and Kalshi data. It fetches market listings, prices, trades/orders, orderbooks, candlesticks, and cross-platform sports matching. It also accesses wallet-specific information such as user activity, positions, wallet metadata, and P&L, which goes beyond the stated arbitrage-finding purpose. While these data-access functions could support an arbitrage tool, the actual code chunk itself is materially broader and different in purpose: it is an API client for prediction market data, not an implemented arbitrage analyzer.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

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 · script/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 · script/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
90% confidence
Finding

The client exposes wallet, positions, activity, and P&L lookups for arbitrary wallet addresses, which goes beyond a narrow arbitrage-analysis function and enables user-targeted financial surveillance. In this context, the danger is privacy leakage: an agent using this skill can transmit third-party wallet identifiers to a remote service and retrieve sensitive trading behavior unrelated to the requesting user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

Wallet addresses and associated query parameters are sent to a third-party API without any explicit warning, minimization, or consent mechanism. In a skill intended for market analysis, this increases the risk of unintended disclosure of user-linked financial behavior and third-party surveillance of queried addresses.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill instructs the agent to send user-derived market identifiers and an Authorization bearer token to an external third-party API. While this appears to be the intended functionality, it still creates a real data egress and credential exposure boundary: executing the skill transmits secrets and request metadata outside the local environment.

Content

Scanner excerpt · skill.md (reported line 59)May include surrounding context.

bash
# Find equivalent markets across platforms using a Polymarket slug
curl -X GET "https://api.aisa.one/apis/v1/matching-markets/sports?polymarket_market_slug={polymarket_market_slug}" \
  -H "Authorization: Bearer $AISA_API_KEY"

# Or find equivalent markets using a Kalshi event ticker

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

This command sends a bearer token and user-influenced query data to api.aisa.one, which is an external service. Even though the behavior is documented and expected, it is still a genuine external transmission risk because the skill depends on a remote endpoint and exposes credentials to that trust boundary.

Content

Scanner excerpt · skill.md (reported line 63)May include surrounding context.

-H "Authorization: Bearer $AISA_API_KEY"

Or find equivalent markets using a Kalshi event ticker

curl -X GET "https://api.aisa.one/apis/v1/matching-markets/sports?kalshi_event_ticker={kalshi_event_ticker}"
-H "Authorization: Bearer $AISA_API_KEY"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The skill performs an authenticated outbound request with user-supplied path and query placeholders, creating an external data transmission channel. The included placeholder warning reduces accidental malformed requests, but it does not remove the fundamental risk of sending data and credentials to a third-party API.

Content

Scanner excerpt · skill.md (reported line 71)May include surrounding context.

bash
# Find all matching sports markets across platforms for a specific date
curl -X GET "https://api.aisa.one/apis/v1/matching-markets/sports/{sport}?date={date}" \
  -H "Authorization: Bearer $AISA_API_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This instruction sends an authenticated request containing a market token identifier to an external API. The main concern is not arbitrary code execution but the deliberate transfer of data and use of a secret against a remote service, which can expose usage patterns, metadata, and credentials if mishandled.

Content

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

bash
# token_id comes from side_a.id or side_b.id in /polymarket/markets response
curl -X GET "https://api.aisa.one/apis/v1/polymarket/market-price/{token_id}" \
  -H "Authorization: Bearer $AISA_API_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill directs the runner to query a third-party endpoint with an Authorization header, which constitutes a real outbound transmission finding. In context this is expected product behavior, but from a security perspective it still means sensitive credentials are being used outside the host and external service compromise or misuse could affect confidentiality and billing.

Content

Scanner excerpt · skill.md (reported line 91)May include surrounding context.

bash
# market_ticker comes from /kalshi/markets response
curl -X GET "https://api.aisa.one/apis/v1/kalshi/market-price/{market_ticker}" \
  -H "Authorization: Bearer $AISA_API_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The orderbook lookup sends token_id data plus the bearer token to an external API, so the external transmission is genuine. Although the data itself is not highly sensitive, the request still reveals operator activity and consumes authenticated API access, making it security-relevant.

Content

Scanner excerpt · skill.md (reported line 103)May include surrounding context.

bash
# token_id comes from side_a.id or side_b.id in /polymarket/markets response
curl -X GET "https://api.aisa.one/apis/v1/polymarket/orderbooks?token_id={token_id}" \
  -H "Authorization: Bearer $AISA_API_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This curl example transmits a ticker value and bearer token to a third-party service, creating a clear external communication path. The skill context makes this less suspicious than hidden exfiltration because the destination and purpose are explicit, but it remains a true vulnerability class for environments that restrict outbound data flows or secret use.

Content

Scanner excerpt · skill.md (reported line 111)May include surrounding context.

bash
# ticker is the same value as market_ticker from /kalshi/markets response
curl -X GET "https://api.aisa.one/apis/v1/kalshi/orderbooks?ticker={ticker}" \
  -H "Authorization: Bearer $AISA_API_KEY"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown includes commands to fetch a wallet's positions and profit/loss, which can expose sensitive financial information, but it does not warn users about privacy implications or handling of wallet-linked data. Under the markdown-file criteria for SQP-2, data-affecting or privacy-relevant behavior should be disclosed.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The client automatically reads AISA_API_KEY from the process environment. For a skill described only as finding and analyzing arbitrage opportunities, credential harvesting from environment variables is an additional capability not disclosed in the manifest, even though it is used here for authenticated API access.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes a general-purpose arbitrage finder across prediction markets like Polymarket and Kalshi, but this code implements a distinct cross-platform sports market matching feature. While related to comparison, it is a specialized market-discovery function rather than arbitrage analysis, so the implemented scope does not cleanly match the stated description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.