Back to skill

Security audit

agent-guard

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed trading-protection sidecar, but it asks for live private-key trading authority and can enable automatic fund-affecting exits with too little separation between setup and live authorization.

Install only after reviewing the external npm package and running in dry-run first. Use a dedicated limited wallet or delegated signer, avoid primary wallets, avoid committing or logging private keys, and do not enable EXIT_PK/AGENT_GUARD_EXIT_PK unless you intentionally want the watcher to place real protective exits. Treat the Docker and npx flows as live automation when credentials are present.

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)

T08 · Insecure Dependencies

Error
Location
scripts/package.json:6
Finding
Privileged Trading Logic Is Loaded from an Unverified npm Dependency<![CDATA[ ## Vulnerability Details **File Location**: `scripts/package.json:6-8`, `scripts/setup.mjs:9-23`, `scripts/start-mcp.mjs:9-17`, `scripts/start-watcher.mjs:9-15`, `NAUTILUS-SIDECAR.md:49-57` **Vulnerability Type**: Supply-chain execution of externally maintained code without a committed integrity lock **Risk Level**: High ### Complete Code Snippets `scripts/package.json:6-8`: ```json "dependencies": { "@hypelens/hypelens-agent-guard": "0.1.18" } ``` `scripts/setup.mjs:9-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); ``` `scripts/start-mcp.mjs:9-17`: ```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); ``` `scripts/start-watcher.mjs:9-15`: ```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); ``` `NAUTILUS-SIDECAR.md:49-57`: ```yaml services: agent-guard-watcher: image: node:22-bookworm-slim working_dir: /app command: bash -lc "npm i @hypelens/hypelens-agent-guard@0.1.18 && npx hypelens-agent-guard setup --wallet $FUNDER && npx h ...[truncated 3141 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Commit a package lockfile generated by the selected package manager and require immutable, reproducible installation such as `npm ci`. 2. Record and independently verify npm integrity hashes and package provenance before deployment. 3. Vendor or otherwise include the complete security-sensitive implementation in the review scope. 4. Do not install packages during container startup. Build a reviewed image in CI and deploy it by immutable image digest. 5. Pin the base container image by digest rather than using only `node:22-bookworm-slim`. 6. Audit the complete transitive dependency graph and enable automated dependency and provenance monitoring. 7. Avoid trusting dependency-controlled `bin` paths for privileged launchers. Resolve an explicitly reviewed entry point and verify its artifact hash before import. 8. Run the MCP server and watcher as a dedicated, unprivileged operating-system user or container. 9. Restrict outbound networking to the exact APIs required for market data and transaction submission. 10. Mount configuration read-only where possible and separate heartbeat output from security policy files. 11. Use a delegated signer with protocol-level restrictions instead of exposing a broadly capable funder key to the dependency. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:83
Finding
Private-Key Presence Automatically Transitions the Watcher into Live Trading Mode<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:83-99`, `BOT.md:5`, `NAUTILUS-SIDECAR.md:5-9`, `NAUTILUS-SIDECAR.md:24-26`, `NAUTILUS-SIDECAR.md:49-57` **Vulnerability Type**: Unsafe live-mode activation and plaintext secret exposure through process environment variables **Risk Level**: High ### Complete Code Snippets `SKILL.md:83-99`: ```markdown 1. `guard_status` / `guard_heartbeat` / aliases `check_exits` — sidecar probes + heartbeat 2. `guard_positions` — Data API + optional HL clearinghouse 3. Optional `guard_set_policy` / `set_exit_rules` tighten floors (cannot loosen YAML) 4. `guard_arm` / `go_live` when EXIT_PK present 5. Keep watcher running — writes `state/heartbeat.json` each tick 6. Live: `AGENT_GUARD_EXIT_PK` (+ optional `AGENT_GUARD_HL_PK`) — setup **auto-flips** `exits.dryRun:false` when EXIT_PK set 7. `guard_disarm` only with `confirm:true` + `confirmDisarm:"DISARM"` ## Fee / volume - Default dryRun = **free** - Live arm = **fee-on-protection**: PM protective SELLs bake Zac `builderCode` (PM LIVE rates still **0/0** until cooldown flip — do not claim PM fee $ yet); HL protective reduces attach builder `0x9548…` @ **1bp NOW** on FILLED - Never trade `0x9548B8E9554a1968843B3C380431b10996247c88` ## LIVE-ARM (0.1.18) `EXIT_PK` / `AGENT_GUARD_EXIT_PK` → setup **auto-flips** `exits.dryRun:false`. Compose entrypoint fail-closed. Proof: `AGENT_GUARD_EXIT_ON_BREACH=1` → exit **10** on first dry breach. ``` `BOT.md:5`: ```markdown 3. Arm: `node setup.mjs --wallet 0xYourFundedPmProxy` (or `npx @hypelens/hypelens-agent-guard@0.1.18 setup --wallet 0x…`) — **dry-run stops arm immediately**; live = `EXIT_PK` + `exits.dryRun:false`. ``` `NAUTILUS-SIDECAR.md:5-9`: ```bash npx @hypelens/hypelens-agent-guard@0.1.18 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.18 watcher ``` `NAUTILUS-SIDECAR.md:24-2 ...[truncated 3744 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never activate live mode solely because a private key is present. 2. Require a separate explicit command such as `guard_arm --live --confirm LIVE_TRADING`, with confirmation bound to the wallet address, policy hash, environment, and expiration time. 3. Keep setup in dry-run mode by default regardless of available credentials. 4. Display the complete effective policy and affected wallet before activation, then require an independent operator confirmation. 5. Separate secret provisioning from policy configuration and from live authorization. 6. Replace raw private keys with delegated, revocable credentials restricted to protective sales, approved contracts, maximum order size, daily notional, and expiration time. 7. Use a secret manager, Docker secret, hardware signer, or isolated signing service instead of ordinary environment variables. 8. Do not persist private keys in generated policy, state, shell history, logs, or heartbeat files. 9. Add transaction-level controls, including maximum size, maximum daily loss, allowed markets, allowed destination contracts, price-deviation limits, and rate limits. 10. Require renewed confirmation after policy changes, watcher restarts, signer changes, or heartbeat recovery. 11. Validate market data through independent sources and fail closed on stale, inconsistent, or malformed data. 12. Provide a documented emergency revocation procedure and ensure operators can disable signer authority independently of the watcher. ]]>
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 (6)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation explicitly instructs users to enable live operation by supplying a private key and disabling dry-run mode, but it does not provide a clear warning that this can trigger real on-chain or exchange actions affecting funds. In a trading-protection skill, this is especially sensitive because users may treat setup commands as routine and unknowingly authorize irreversible automated exits or account actions.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The document instructs users to set an environment variable containing a live private key (`AGENT_GUARD_EXIT_PK`) that can execute SELL orders, but it does not provide prominent guidance on secret handling, wallet scoping, or the financial consequences of granting automated trade authority. In this skill's context, the key is specifically intended to control funded Polymarket/Hyperliquid positions, so mishandling or overbroad reuse of the key could lead to unauthorized liquidation or theft-impacting trades.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The instructions tell users to disable dry-run and note that setup may auto-flip `exits.dryRun:false`, effectively enabling live automated exits, but the warning about real trading behavior is not prominent or safety-gated. Because this is a trading protection sidecar operating outside the main LLM and designed to act automatically on breaches, users could unintentionally activate live order placement and flatten positions without fully understanding the effect.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The compose workflow exports a live exit private key into the shell environment and immediately starts unattended automation, yet it omits explicit warnings about environment-variable exposure, container inspection risk, and real-money execution. In this skill, the automation is specifically intended to place protective SELLs for active funded positions, so weak secret handling combined with immediate launch materially increases the chance of credential compromise or unintended liquidation events.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The manifest description contains very broad activation cues such as generic stop-loss, risk, drawdown, go live, and references to many adjacent tools and workflows. In an agent-routing system, this can cause the skill to trigger for loosely related trading requests, increasing the chance it is invoked outside its intended guard-only role and influences sensitive financial actions unnecessarily.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The recommendsWhen field includes the wildcard trigger '*place*', which is ambiguous and can match a wide range of unrelated requests containing that substring. In a trading context, overbroad recommendation logic is risky because it can cause the skill to be suggested or chained into workflows where its installation or use is not appropriate, increasing the chance of unintended operational changes around live positions.

Static analysis

No suspicious patterns detected.