Back to skill

Security audit

Polymarket Portfolio Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill is a Review item because it monitors Polymarket but also uses wallet secrets and automatically runs unbundled trading scripts that can spend funds without per-trade approval.

Only install this after reviewing or supplying the helper scripts yourself, using a dedicated low-balance wallet, pinning dependencies, and confirming that automatic trading is intentionally enabled. Do not put a main wallet private key or unrelated secrets in the same .env file, and do not run it from cron until spending limits and circuit-breaker behavior are clear.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (4)

T08 · Insecure Dependencies

Error
Location
SKILL.md:30
Finding

Unpinned Security-Sensitive Third-Party Dependencies

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
monitor.py:131
Finding

Private Key Used for a Read-Only Operation and Inherited by Child Processes

Content
View full analysis
= MIN_DEPLOY and not breaker_paused: # Try sports reinvest first reinvest_output = run_script("auto_reinvest.py") time.sleep(2) # Then weather scanner weather_output = run_script("weather_scanner.py", ["--buy"]) ``` ### Technical Analysis The monitor loads a wallet private key and gives it to `ClobClient` merely to obtain the collateral balance. This does not follow least privilege for a monitoring workflow when a public wallet-balance or read-only query can satisfy the requirement. In addition, `subprocess.run` is called without an explicit `env` argument. Python therefore passes the parent environment to each child process, including `PRIVATE_KEY`, Telegram credential ...[truncated 1296 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
monitor.py:142
Finding

Automatic Execution of Unbundled Financial-Action Scripts

Content
View full analysis
= MIN_DEPLOY and not breaker_paused: # Try sports reinvest first reinvest_output = run_script("auto_reinvest.py") time.sleep(2) # Then weather scanner weather_output = run_script("weather_scanner.py", ["--buy"]) elif balance >= MIN_DEPLOY and breaker_paused: alerts.append(breaker_msg) ``` ### Technical Analysis The monitor automatically runs `exit_manager.py`, `auto_reinvest.py`, and `weather_scanner.py`, but none of those files is included in the reviewed project. Their implementation, authorization model, transaction limits, and secret handling therefore cannot be audited. The weather scanner is explicitly launched with `--buy`, demonstrating that the integration is intended to perform financial actions rather than merely report opportunities. When the balance reaches the hardcoded threshold, scripts execute without interactive confirmation, integrity validation, or a trusted-script manifest. The documented cron configuration can repeat this behavior every 30 minutes. The script names are fixe ...[truncated 1273 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
monitor.py:49
Finding

Local Circuit-Breaker State Can Be Reset or Unpaused During the Same Day

Content
View full analysis
-CIRCUIT_BREAKER_PCT: daily["paused"] = False save_daily_pnl(daily) save_daily_pnl(daily) return False, "" ``` ```python if balance >= MIN_DEPLOY and not breaker_paused: # Try sports reinvest first reinvest_output = run_script("auto_reinvest.py") time.sleep(2) # Then weather scanner weather_output = run_script("weather_scanner.py", ["--buy"]) ``` ### Technical Analysis The financial safety decision relies on `.daily_pnl.json`, an unauthenticated local JSON file. If the file is deleted, replaced, or changed to another date, the monitor initializes a new start-of-day portfolio baseline and returns without pausing. No integrity check, ownership validation, locking, or atomic update is used. The code also clears `paused` when portfolio value rises above the loss threshold during the same day. This conflicts with the documented behavior that all new trades remain paused until the following day. A temporary price recovery can therefore reactivate automated purchases before the intended reset. Malformed JSON causes an uncaught fa ...[truncated 1282 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Tainted flow: 'req' from os.environ.get (line 115, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · monitor.py (reported line 119)May include surrounding context.

python
f"{DATA_API}/positions?user={wallet}&sizeThreshold=0.01&limit=100",
        headers={"User-Agent": "ClawdipusRex/1.0"}
    )
    with urllib.request.urlopen(req, timeout=10) as r:
        data = json.loads(r.read())
    return data if isinstance(data, list) else data.get("data", [])

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · monitor.py (reported line 31)May include surrounding context.

python
GAMMA_API = "https://gamma-api.polymarket.com"

def load_env():
    env_path = Path(__file__).parent / ".env"
    if env_path.exists():
        for line in env_path.read_text().splitlines():
            line = line.strip()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill advertises automatic reinvestment that can execute trades when available cash reaches a threshold, but it does not present a clear upfront warning that real funds may be committed without per-trade confirmation. In a financial trading context, this creates a meaningful risk of unintended asset deployment, especially when paired with cron-based unattended execution and integration with other trading scripts.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file presents itself as a monitor, but it also automatically executes trading automation scripts that can place or manage positions. In a security review context, this concealment-by-omission is dangerous because operators may approve or schedule the skill expecting read-only behavior while it performs state-changing financial actions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The top-level documentation explicitly claims 'Reports P&L to Telegram' as part of the skill's behavior. In the implementation, notifications are assembled and emitted with print statements only, with no Telegram API call, webhook, bot client, or message transport present.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · monitor.py (reported line 140)May include surrounding context.

python
cmd = ["python3", str(Path(__file__).parent / script)]
    if extra_args:
        cmd.extend(extra_args)
    r = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
    return (r.stdout + r.stderr).strip()

def main():

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The module docstring states that P&L is reported to Telegram, presenting a fixed communication channel in natural language without indicating any user choice or opt-in. This is a mild policy concern because it prescribes a specific reporting medium rather than offering configurable notification preferences.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.