Back to skill

Security audit

polymarket-risk

Security checks for vulnerabilities and agentic risk

Overview

This trading risk skill is purpose-aligned, but it needs Review because it can automate live sell exits with a wallet key and has under-scoped execution and attribution risks.

Only install after carefully reviewing the trading policy and signer scope. Treat AGENT_GUARD_EXIT_PK or EXIT_PK as a private key that can authorize sell actions, keep dry-run enabled until you have verified the wallet, markets, thresholds, and builder attribution, and avoid runtime npx/Docker install flows with live credentials present.

Vulnerability Patterns
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/setup.mjs:11
Finding
Out-of-Project Fallback Allows Untrusted Code Execution<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/setup.mjs:11-22` - `scripts/start-watcher.mjs:10-28` - `scripts/start-mcp.mjs:10-31` **Vulnerability Type**: `T07: Tool Hijacking and Spoofing` **Risk Level**: High ### Vulnerable Code `scripts/setup.mjs:11-22`: ```js let entry; try { const pkgJson = require.resolve('@hypelens/hypelens-agent-guard/package.json'); entry = join(dirname(pkgJson), 'bin', 'agent-guard.js'); } catch { entry = join(scriptsDir, '..', '..', 'bin', 'agent-guard.js'); } if (!existsSync(entry)) { console.error('Missing @hypelens/hypelens-agent-guard. Run: npm install'); process.exit(1); } process.argv = [process.argv[0], entry, 'setup', '--scripts-dir', scriptsDir, ...process.argv.slice(2)]; await import(pathToFileURL(entry).href); ``` `scripts/start-watcher.mjs:10-28`: ```js try { const pkgJson = require.resolve('@hypelens/hypelens-agent-guard/package.json'); const pkg = require(pkgJson); const binRel = (pkg.bin && pkg.bin['agent-guard-watcher']) || 'bin/agent-guard-watcher.js'; const entry = join(dirname(pkgJson), binRel); await import(pathToFileURL(entry).href); } catch (e) { try { const localEntry = join( dirname(fileURLToPath(import.meta.url)), '..', '..', 'bin', 'agent-guard-watcher.js', ); await import(pathToFileURL(localEntry).href); } catch { console.error('Missing dependency. Run: npm install (in this scripts/ folder)'); console.error(String(e && e.message ? e.message : e)); process.exit(1); } } ``` `scripts/start-mcp.mjs:10-31`: ```js try { const pkgJson = require.resolve('@hypelens/hypelens-agent-guard/package.json'); const pkg = require(pkgJson); const binRel = (pkg.bin && (pkg.bin['agent-guard-mcp'] || pkg.bin['agent-guard'])) || 'bin/agent-guard-mcp.js'; const entry = join(dirname(pkgJson), binRel); await import(pathToFileURL(entry).href); } catch (e) { try { const localEntry = join( dirname(file ...[truncated 2236 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all `../../bin` fallback imports from the published Skill. - Fail closed if the integrity-pinned dependency cannot be loaded. - Catch dependency-resolution errors separately from runtime errors; do not activate a fallback when legitimate code throws during execution. - If a development fallback is necessary, require an explicit development-only flag. - Resolve the fallback with `realpath` and verify that it remains inside an explicitly trusted repository root. - Refuse to run fallback code when wallet credentials are present. - Execute sensitive trading components in a restricted process with minimal filesystem access and a tightly scoped signer. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
NAUTILUS-SIDECAR.md:6
Finding
Wallet Private Key Is Exposed to Third-Party Runtime and Container Environments<![CDATA[ ## Vulnerability Details **File Location**: - `NAUTILUS-SIDECAR.md:6-9` - `NAUTILUS-SIDECAR.md:18-19` - `NAUTILUS-SIDECAR.md:50-56` - `ELIZA-COMPANION.md:8-10` - `BOT.md:5` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code `NAUTILUS-SIDECAR.md:6-9`: ```bash npx @hypelens/hypelens-agent-guard@0.1.17 setup --wallet 0xYourFunder export AGENT_GUARD_EXIT_PK=0xYourExitKey # can SELL funder positions # set exits.dryRun: false in the written policy npx @hypelens/hypelens-agent-guard@0.1.17 watcher ``` `NAUTILUS-SIDECAR.md:18-19`: ```bash export FUNDER=0xYourFunder EXIT_PK=0xYourExitKey docker compose up -d --build ``` `NAUTILUS-SIDECAR.md:50-56`: ```yaml command: bash -lc "npm i @hypelens/hypelens-agent-guard@0.1.17 && npx hypelens-agent-guard setup --wallet $FUNDER && npx hypelens-agent-guard watcher" environment: - AGENT_GUARD_EXIT_PK=${EXIT_PK} volumes: - ./agent-guard-state:/app/state - ./agent-guard-policy:/app/config ``` `ELIZA-COMPANION.md:8-10`: ```bash npx @hypelens/hypelens-agent-guard@0.1.16 setup --wallet 0xYourFunder npx @hypelens/hypelens-agent-guard@0.1.16 watcher # live: AGENT_GUARD_EXIT_PK + exits.dryRun:false ``` `BOT.md:5`: ```text 3. Arm: `node setup.mjs --wallet 0xYourFundedPmProxy` (or `npx @hypelens/hypelens-agent-guard@0.1.16 setup --wallet 0x…`) — **dry-run stops arm immediately**; live = `EXIT_PK` + `exits.dryRun:false`. ``` ### Technical Analysis The deployment instructions place a transaction-authorizing private key in a normal process or container environment variable. The documentation explicitly states that this key can sell positions belonging to the funder wallet. Environment variables are accessible to the process receiving them and may also be exposed through container inspection, privileged host processes, debugging tools, crash diagnostics, accidental logging, or compromised dependencies. The implementation consuming the secret is not included in t ...[truncated 1134 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not use the funder wallet's unrestricted private key. - Use a dedicated, narrowly scoped delegated signer with minimum balances, limited approvals, and explicit transaction constraints. - Store secrets in a platform secret manager or a protected mounted file rather than an ordinary environment variable. - Apply restrictive filesystem permissions and prevent secret files from being committed, logged, or included in container images. - Pin and verify the container image and all executable package artifacts before supplying credentials. - Separate installation from execution so no package download occurs in a process that already holds the signing key. - Document key rotation, emergency revocation, allowance removal, and maximum exposure limits. - Keep dry-run enabled until the user explicitly confirms the policy and signer scope. ]]>

T08 · Insecure Dependencies

Warning
Location
NAUTILUS-SIDECAR.md:52
Finding
Runtime Retrieval and Execution of Opaque npm Code with Trading Authority<![CDATA[ ## Vulnerability Details **File Location**: - `ELIZA-COMPANION.md:8-9` - `NAUTILUS-SIDECAR.md:6-9` - `NAUTILUS-SIDECAR.md:52` - `BOT.md:5` - `scripts/setup.mjs:11-23` - `scripts/start-watcher.mjs:10-14` - `scripts/start-mcp.mjs:10-16` **Vulnerability Type**: `T08: Insecure Dependencies` **Risk Level**: Medium ### Vulnerable Code `ELIZA-COMPANION.md:8-9`: ```bash npx @hypelens/hypelens-agent-guard@0.1.16 setup --wallet 0xYourFunder npx @hypelens/hypelens-agent-guard@0.1.16 watcher ``` `NAUTILUS-SIDECAR.md:6-9`: ```bash npx @hypelens/hypelens-agent-guard@0.1.17 setup --wallet 0xYourFunder export AGENT_GUARD_EXIT_PK=0xYourExitKey # can SELL funder positions # set exits.dryRun: false in the written policy npx @hypelens/hypelens-agent-guard@0.1.17 watcher ``` `NAUTILUS-SIDECAR.md:52-54`: ```yaml command: bash -lc "npm i @hypelens/hypelens-agent-guard@0.1.17 && npx hypelens-agent-guard setup --wallet $FUNDER && npx hypelens-agent-guard watcher" environment: - AGENT_GUARD_EXIT_PK=${EXIT_PK} ``` `scripts/setup.mjs:11-23`: ```js let entry; try { const pkgJson = require.resolve('@hypelens/hypelens-agent-guard/package.json'); entry = join(dirname(pkgJson), 'bin', 'agent-guard.js'); } catch { entry = join(scriptsDir, '..', '..', 'bin', 'agent-guard.js'); } if (!existsSync(entry)) { console.error('Missing @hypelens/hypelens-agent-guard. Run: npm install'); process.exit(1); } process.argv = [process.argv[0], entry, 'setup', '--scripts-dir', scriptsDir, ...process.argv.slice(2)]; await import(pathToFileURL(entry).href); ``` The lockfile partially mitigates substitution for local installation: ```json "node_modules/@hypelens/hypelens-agent-guard": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/@hypelens/hypelens-agent-guard/-/hypelens-agent-guard-0.1.17.tgz", "integrity": "sha512-oDPjyJHHatIM69eiGCthlxtkKewFB8JztWgS+sFMReQD6qwd/N7aI3/PJWVdXtif0V+33ZtnVsfVnt9EyOBwgA==" } ``` ### Technical Analysis The Skill's substantiv ...[truncated 1785 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Vendor and audit the executable dependency, or publish its reviewed source alongside the Skill. - Install with `npm ci` using the committed lockfile rather than direct `npx` or `npm install` commands. - Verify package integrity and publisher provenance before execution. - Publish signed release artifacts and document checksum or signature verification. - Separate dependency installation from the credential-bearing runtime. - Build an immutable, pinned container image in a controlled environment rather than installing packages during container startup. - Run the watcher under a dedicated low-privilege account with restricted filesystem and network access. - Use a scoped delegated signer so dependency compromise cannot control the primary funded wallet. ]]>

other

Warning
Location
NAUTILUS-SIDECAR.md:25
Finding
Protective Trades Apply Developer-Specific Builder Attribution<![CDATA[ ## Vulnerability Details **File Location**: - `ELIZA-COMPANION.md:15` - `NAUTILUS-SIDECAR.md:25` - `NAUTILUS-SIDECAR.md:31` - `BOT.md:7` **Vulnerability Type**: `other: Undisclosed or unnecessary financial attribution` **Risk Level**: Medium ### Vulnerable Code `ELIZA-COMPANION.md:15`: ```text Protective SELLs stamp Zac builderCode. Prefer Nautilus sidecar discovery first (higher notional). Eliza volume unknown — treat as stretch until proven. ``` `NAUTILUS-SIDECAR.md:25`: ```text Same funder wallet as Nautilus. Dry-run arms immediately. EXIT_PK → setup auto-flips exits.dryRun:false (0.1.17+) so protective SELLs stamp Zac builderCode 0x6f751c1d…7329. ``` `NAUTILUS-SIDECAR.md:31`: ```text The adapter also hard-codes its own builderCode (fee rate 0). Entries stay Nautilus-attributed. This watcher sits beside the live node and places protective SELLs with Zac code → warm attribution now (fee $ after taker/maker rates >0; ~1% taker ~19–20 Sep). ``` `BOT.md:7`: ```text 5. Tools: `stop` · `trailing` · `portfolio` · `heartbeat` (+ `guard_tick` / watcher). Never trade `0x9548…`. HL protective FILLED = **1bp NOW**; PM builderCode baked (rates LIVE still **0/0** until flip). ``` ### Technical Analysis The documentation states that protective SELL orders are stamped with a fixed builder code associated with a named third party and discusses future fee revenue. Builder attribution is not inherently necessary to monitor positions or enforce stop-loss policies. Although the companion documentation discloses the attribution, the primary installation flow does not clearly present it as a separate, informed user choice with exact fee implications. The audited wrapper code also exposes no local option to remove or replace the attribution because the transaction implementation resides in the external dependency. This behavior creates a potential conflict of interest: users install the Skill for risk management, while resulting transactions may provide attri ...[truncated 765 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Disable third-party builder attribution by default. - Require explicit, informed opt-in before attaching any builder code. - Display the exact builder identity, code, current fee rate, and possible future fee implications. - Provide a supported configuration option to remove or replace the builder code. - Keep risk-control behavior independent from referral, attribution, or monetization features. - Record the selected attribution policy in the generated configuration and display it before live mode is enabled. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instructions tell the user to export a live private key and run a watcher that can place real SELL orders, but they do not prominently warn about key-handling, irreversible account impact, or the transition from dry-run to live execution. In a trading sidecar, this omission is dangerous because copy/paste setup can cause unintended live trades or expose a credential capable of liquidating positions.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The one-line install/start workflow encourages immediate execution of setup and watcher commands that can place live protective orders, yet it lacks an unavoidable warning about real trading consequences and credential sensitivity. Because this skill is explicitly intended for Polymarket risk automation, terse install commands materially increase the chance of users launching a live seller with the wrong wallet, wrong policy, or misunderstood behavior.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The skill advertises an extremely broad trigger list, including generic trading and risk-management phrases, which increases the chance of accidental or context-inappropriate invocation. In this context, unintended activation is more dangerous than usual because the skill is tied to live trading sidecar behavior and can influence automated exit workflows around real positions.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The instructions tell the user to install dependencies, run setup against a funded wallet, and start a watcher that manages stop-loss and exit behavior, but they do not prominently warn that this may trigger automated exits on live positions. In a live trading context, that omission can cause users to enable automation they do not fully understand, leading to unintended trades, forced liquidations of positions, or financial loss.

Static analysis

No suspicious patterns detected.