Back to skill

Security audit

Polymarket Oracle

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Polymarket scanning/trading skill, but its setup instructions repeatedly encourage storing a powerful wallet private key in long-lived files even though the bot does not need it at runtime.

Review carefully before installing. Do not store a real wallet private key in systemd, ~/.bashrc, a project .env, or /etc/polymarket-oracle/credentials.env. If testing, use simulation mode or a low-value wallet, generate API credentials on a trusted local machine, remove WALLET_PRIVATE_KEY from runtime configuration, pin and verify dependencies used for credential generation, and confirm the code’s actual trading behavior before using real funds.

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

T09 · Insecure Skill Coding Practices

Error
Location
SYSTEMD_SETUP.md:53
Finding
Unnecessary Persistent Storage of the Wallet Private Key<![CDATA[ ## Vulnerability Details **File Locations**: - `SYSTEMD_SETUP.md:53-59` - `SYSTEMD_SETUP.md:344-368` - `CONFIGURATION.md:256-281` - `CONFIGURATION.md:602-612` - `README.md:198-210` - `polymarket_oracle.py:35-41` **Vulnerability Type**: Unnecessary collection and persistent plaintext storage of a wallet private key **Risk Level**: High ### Vulnerable Code and Configuration `SYSTEMD_SETUP.md:53-59` instructs users to place the wallet private key directly in a systemd unit: ```ini # Environment Variables - REPLACE WITH YOUR CREDENTIALS Environment="POLYMARKET_API_KEY=your_polymarket_api_key_here" Environment="POLYMARKET_SECRET=your_polymarket_secret_here" Environment="POLYMARKET_PASSPHRASE=your_polymarket_passphrase_here" Environment="WALLET_PRIVATE_KEY=your_wallet_private_key_here" Environment="TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here" Environment="TELEGRAM_CHAT_ID=your_telegram_chat_id_here" ``` `SYSTEMD_SETUP.md:344-368` also recommends persistently storing the key in a server-side environment file: ```bash # Create credentials file sudo mkdir -p /etc/polymarket-oracle sudo nano /etc/polymarket-oracle/credentials.env # Content: POLYMARKET_API_KEY=your_key POLYMARKET_SECRET=your_secret POLYMARKET_PASSPHRASE=your_passphrase WALLET_PRIVATE_KEY=your_private_key TELEGRAM_BOT_TOKEN=your_token TELEGRAM_CHAT_ID=your_id POLYMARKET_CAPITAL=10000 # Protect file sudo chmod 600 /etc/polymarket-oracle/credentials.env sudo chown root:root /etc/polymarket-oracle/credentials.env ``` The service is then configured to load this file: ```ini EnvironmentFile=/etc/polymarket-oracle/credentials.env ``` `CONFIGURATION.md:256-281` similarly instructs users to export the private key and make it persistent: ```bash # Polymarket credentials export POLYMARKET_API_KEY="your_api_key" export POLYMARKET_SECRET="your_secret" export POLYMARKET_PASSPHRASE="your_passphrase" export WALLET_PRIVATE_KEY="0x..." # Telegram (optional) export TELEGRAM_BOT_TOKEN="your_bot_toke ...[truncated 4383 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all runtime use of the wallet private key: - Delete `WALLET_PRIVATE_KEY = os.getenv("WALLET_PRIVATE_KEY")` from `polymarket_oracle.py`. - Remove the key from `SKILL.md` runtime requirements. - Remove it from every README, shell, environment-file, and systemd example. 2. Generate Polymarket API credentials only on a trusted local machine: - Use the wallet key only during the one-time credential-generation process. - Do not copy the key to the server running the scanner. - Prefer a dedicated low-value wallet if a signing operation is unavoidable. 3. Store only revocable runtime credentials: - `POLYMARKET_API_KEY` - `POLYMARKET_SECRET` - `POLYMARKET_PASSPHRASE` - Optional Telegram credentials 4. Do not place secrets directly in a systemd unit. Use a dedicated secret store or, at minimum, a root-owned environment file with: - Ownership `root:root` - Mode `0600` - Exclusion from backups and source control - A documented credential-rotation process 5. Run the service as a dedicated unprivileged account rather than suggesting `root`: - Use a separate user with no interactive login. - Grant write access only to the required log directory. - Retain `NoNewPrivileges=true` and add further systemd sandboxing where compatible. 6. Revoke and rotate any credentials deployed according to the existing instructions. If a real wallet private key was stored on a server, migrate funds to a newly generated wallet because the private key itself cannot be safely rotated. ]]>

T08 · Insecure Dependencies

Warning
Location
CONFIGURATION.md:50
Finding
Unpinned Third-Party Package Used in Wallet Credential Generation<![CDATA[ ## Vulnerability Details **File Locations**: - `README.md:179-190` - `CONFIGURATION.md:50-71` - `CONFIGURATION.md:98-113` **Vulnerability Type**: Unsafe and unpinned dependency installation in a private-key handling workflow **Risk Level**: Medium ### Vulnerable Installation and Execution Instructions `README.md:179-190` installs the latest available package without a version or integrity constraint and then imports it: ```bash # Using py-clob-client pip install py-clob-client python3 << EOF from py_clob_client.client import ClobClient client = ClobClient("https://clob.polymarket.com") creds = client.create_api_key() print("API Key:", creds['apiKey']) print("Secret:", creds['secret']) print("Passphrase:", creds['passphrase']) EOF ``` `CONFIGURATION.md:50-71` uses the same unpinned dependency while passing it the wallet private key: ```bash # Install official client pip install py-clob-client # Generate credentials python3 << 'EOF' from py_clob_client.client import ClobClient # Initialize client client = ClobClient( host="https://clob.polymarket.com", key="YOUR_WALLET_PRIVATE_KEY", # From MetaMask chain_id=137 # Polygon ) # Create API credentials creds = client.create_api_key() print("=== SAVE THESE CREDENTIALS ===") print(f"API Key: {creds['apiKey']}") print(f"Secret: {creds['secret']}") print(f"Passphrase: {creds['passphrase']}") print("===============================") EOF ``` ### Technical Analysis The command `pip install py-clob-client` resolves and installs the currently available package version from the configured Python package index. The documentation provides no: - Exact version pin - Cryptographic hash verification - Lock file - Isolated virtual environment - Verified download artifact - Reproducible installation procedure - Guidance for confirming publisher or package-index provenance This dependency is subsequently imported and receives the wallet private key. Therefore, a compromised package release, publishe ...[truncated 1644 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the client to a specifically reviewed release rather than installing the latest release implicitly: ```bash python3 -m pip install "py-clob-client==REVIEWED_VERSION" ``` 2. Use hash verification: - Download and inspect the intended wheel from the official source. - Record its SHA-256 hash. - Install through a requirements file using `--require-hashes`. 3. Perform credential generation in a new isolated virtual environment: ```bash python3 -m venv ./credential-generation-venv ./credential-generation-venv/bin/python -m pip install --upgrade pip ./credential-generation-venv/bin/python -m pip install --require-hashes -r requirements-credentials.txt ``` 4. Verify that the package name, publisher, repository, and release artifact match the official Polymarket client documentation before installation. 5. Review and pin transitive dependencies as well as the direct dependency. 6. Run credential generation on a trusted local machine that does not contain unrelated secrets. Delete the isolated environment after use. 7. Avoid embedding the private key directly in a command or script. Obtain it through a protected interactive mechanism where supported, and ensure it is not retained in shell history, source files, terminal logs, or generated artifacts. 8. Document a response procedure requiring immediate migration to a new wallet if the private key may have been exposed during an unverified dependency installation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (109)

Intent-Code Divergence

Critical
Confidence
100% confidence
Finding
The systemd example embeds WALLET_PRIVATE_KEY directly in the unit configuration even though the guide previously says the private key must never be stored on the server. A systemd unit may be readable by privileged support tooling, backups, misconfigured permissions, process inspection, or accidental sharing, and exposure of this key grants irreversible full wallet control and fund theft.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# On your SERVER (where bot runs)
# Create secure credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Paste ONLY these (NO private key!):
POLYMARKET_API_KEY=your_api_key_from_step1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
❌ Commit WALLET_PRIVATE_KEY to git
❌ Store private key anywhere long-term

# ❌ NEVER use .env file in project directory
❌ cat > .env << 'EOF'
❌ WALLET_PRIVATE_KEY="..."
❌ EOF
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
❌ Commit WALLET_PRIVATE_KEY to git
❌ Store private key anywhere long-term

# ❌ NEVER use .env file in project directory
❌ cat > .env << 'EOF'
❌ WALLET_PRIVATE_KEY="..."
❌ EOF
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
**The bot code uses ONLY API credentials at runtime.**

chmod 600 .env
```

---
Confidence
83% confidence
Finding
The stray 'chmod 600 .env' line appears immediately after a section warning never to use a project .env for the private key, creating contradictory guidance around local secret storage. Even though chmod tightens permissions, this inconsistency can normalize creation of a project-directory .env that may later contain sensitive material and be accidentally committed, backed up, or exposed.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The document explicitly states the wallet private key is only needed once and must never be stored on the server, but later instructs users to export and persist WALLET_PRIVATE_KEY in their shell environment and startup files. This contradiction can lead operators to store a full-control blockchain secret long-term on disk, making theft via local compromise, backups, logs, shell history, or config disclosure far more damaging than exposure of limited-scope API keys.

Missing User Warnings

High
Confidence
98% confidence
Finding
The configuration section instructs users to store the wallet private key in environment variables and to make it permanent in ~/.bashrc or ~/.zshrc, despite earlier advice forbidding long-term server storage. Persisting secrets in shell startup files increases exposure through backups, home directory compromise, debug output, and accidental disclosure to other tools or users on the host.

Missing User Warnings

High
Confidence
99% confidence
Finding
The unit file example places multiple secrets directly in the service definition, including the wallet private key, without a local warning in that section. Inline secrets in unit files are easy to mishandle operationally and especially dangerous here because one of them is a non-revocable wallet key that enables total asset compromise.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented purpose emphasizes scanning and arbitrage detection, but the skill also describes authenticated order placement, Telegram transmission, and local data persistence that are not clearly bounded in the high-level description. This mismatch is dangerous because users or orchestration systems may invoke what appears to be an analysis tool while actually authorizing real-money execution and external data transfer.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
GET /midpoint?token_id={id} - Midpoint price
GET /price?token_id={id}&side={BUY/SELL} - Best price
POST /order - Place order
DELETE /order - Cancel order

Rate limit: Public 60/min, Authenticated 100/min
```
Confidence
91% confidence
Finding
The documented capability includes authenticated POST /order and DELETE /order operations, enabling the skill to place and cancel live market orders. In a real-money trading environment, this is dangerous if exposed without strict parameter validation, explicit authorization boundaries, and execution controls, because malformed or abused parameters can trigger unintended trades, excessive churn, or financial loss.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# Create credentials file
sudo mkdir -p /etc/polymarket-oracle
sudo nano /etc/polymarket-oracle/credentials.env

# Content:
POLYMARKET_API_KEY=your_key
Confidence
90% confidence
Finding
The documentation tells users to create a plaintext credentials file containing exchange secrets, a wallet private key, and messaging tokens. Even with restrictive permissions, plaintext secret files on disk remain high-value targets for local compromise, backup leakage, operator mishandling, or accidental exposure, especially given the presence of a private key that can authorize trades and move funds.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The parity arbitrage detector fabricates the NO price as `1.0 - yes_price` instead of querying the actual opposing market price, so `yes_price + no_price` will always equal 1 and meaningful arbitrage detection cannot occur. In an automated trading bot, flawed strategy logic can cause systematically incorrect signals, missed opportunities, or unsafe execution decisions if later extended to trading, creating direct financial risk.

Session Persistence

Medium
Category
Rogue Agent
Content
## Step 1: Polymarket Account Setup

### **Create Account**

1. Go to https://polymarket.com
2. Click "Connect Wallet"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
POLYMARKET_CAPITAL=10000

# Secure the file
sudo chmod 600 /etc/polymarket-oracle/credentials.env
sudo chown root:root /etc/polymarket-oracle/credentials.env
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
POLYMARKET_CAPITAL=10000

# Secure the file
sudo chmod 600 /etc/polymarket-oracle/credentials.env
sudo chown root:root /etc/polymarket-oracle/credentials.env
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
POLYMARKET_CAPITAL=10000

# Secure the file
sudo chmod 600 /etc/polymarket-oracle/credentials.env
sudo chown root:root /etc/polymarket-oracle/credentials.env
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
### **Make Permanent**

```bash
# Add to ~/.bashrc or ~/.zshrc
cat >> ~/.bashrc << 'EOF'
# Polymarket Oracle
export POLYMARKET_API_KEY="..."
Confidence
97% confidence
Finding
The 'Make Permanent' section tells users to place secrets, including WALLET_PRIVATE_KEY, into ~/.bashrc or ~/.zshrc for automatic loading. That creates long-lived secret persistence in common user files that are broadly exposed to backups, support access, accidental sharing, and post-compromise harvesting, and it directly conflicts with the earlier rule never to store the private key long-term.

Static analysis

No suspicious patterns detected.