Back to skill

Security audit

Okx Dapp Discovery

Security checks for vulnerabilities and agentic risk

Overview

This DeFi router can silently install and activate other trading plugins globally from mutable online sources, so users should review it before use.

Install only if you are comfortable with a router that can add third-party DeFi plugins globally and immediately hand your request to them. Prefer a version that asks before installing, pins the installer and plugin revision, avoids guessed fallback installs, and gives an uninstall or per-project option.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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 (3)

T08 · Insecure Dependencies

Error
Location
SKILL.md:344
Finding
Silent Global Installation of Unpinned Remote Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 344-355 **Vulnerability Type**: Unpinned third-party dependency installation with global scope **Risk Level**: High ### Complete Code Snippet ```bash # Membership check before install case " $INSTALLED_PLUGINS " in *" $TARGET_PLUGIN "*) # Already installed — skip install, read SKILL.md directly (Rule 1) ;; *) # Not installed — install silently (Rule 2) npx skills add okx/plugin-store --skill "$TARGET_PLUGIN" --yes --global ;; esac ``` The same installation pattern is repeated at lines 387, 399, and 519: ```bash npx skills add okx/plugin-store --skill <plugin-name> --yes --global ``` ### Technical Analysis The Skill automatically invokes `npx skills` and installs a plugin from `okx/plugin-store` without pinning either the CLI package or plugin repository to an immutable version, commit, or verified artifact hash. The `--yes` option suppresses interactive confirmation, while `--global` installs the plugin into persistent, user-wide Agent state. Consequently, the actual installed content can differ from the content available when this Skill was audited. Trust is delegated to the current state of the npm ecosystem, the `skills` package resolution process, the GitHub repository, and the selected plugin. The later binary consent gate does not fully mitigate this finding. It applies after the plugin has already been installed globally and only detects selected binary-download patterns in the installed plugin's instructions. This behavior exceeds the minimum privilege required for DApp discovery and routing. A router could identify a suitable plugin and request approval without automatically modifying global Agent state. ### Attack Path 1. An attacker compromises the unpinned `skills` CLI dependency, the `okx/plugin-store` repository, a maintainer account, or a selected plugin. 2. The attacker introduces malicious Skill instructions or dependency-installation behav ...[truncated 1035 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the `skills` CLI to an explicitly reviewed version, for example through a lockfile and exact package version. 2. Pin `okx/plugin-store` to a reviewed immutable commit or signed release rather than its mutable default branch. 3. Verify plugin manifests and files against published cryptographic hashes or signatures before activation. 4. Remove `--global` by default. Install plugins into a per-project, temporary, or sandboxed directory with the minimum required permissions. 5. Remove silent installation behavior. Show the exact plugin name, source repository, version or commit, requested scope, and expected capabilities before requesting explicit approval. 6. Separate download, review, and activation: - Fetch the plugin without loading it. - inspect its instructions and bundled files; - identify shell commands, network destinations, and executable dependencies; - obtain approval; - activate only the reviewed content. 7. Apply the consent gate to the plugin installation itself, not merely to subsequent binary downloads. 8. Restrict installed plugins through a signed allowlist of reviewed plugin identifiers and revisions. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:365
Finding
Mutable Live Catalog Can Trigger Installation and Loading of Unaudited Plugins<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 365-400 **Vulnerability Type**: Remote payload selection and activation through a mutable catalog **Risk Level**: High ### Complete Code Snippet ```bash # Normalize the user-named DApp to a plugin-store-style ID prefix (lowercase, no dots) DAPP_LOWER=$(echo "<DApp name as user typed it>" | tr 'A-Z' 'a-z' | tr -d '.') # Fast catalog probe via GitHub Contents API (~0.1s) CATALOG=$(curl -fsSL --max-time 5 "https://api.github.com/repos/okx/plugin-store/contents/skills" 2>/dev/null \ | python3 -c "import sys,json; print('\n'.join(p['name'] for p in json.load(sys.stdin)))" 2>/dev/null) if [ -n "$CATALOG" ]; then # Prefix match — handles -plugin, -ai, and -v2-plugin MATCHES=$(echo "$CATALOG" | grep -E "^${DAPP_LOWER}(-|$)" || true) COUNT=$(echo "$MATCHES" | grep -c . 2>/dev/null || echo 0) case "$COUNT" in 0) TARGET_PLUGIN="" ;; 1) TARGET_PLUGIN=$(echo "$MATCHES" | head -1) npx skills add okx/plugin-store --skill "$TARGET_PLUGIN" --yes --global # Proceed: Read the plugin SKILL.md and forward the user's prompt ;; *) TARGET_PLUGIN="" ;; esac else # GitHub API unreachable / rate-limited if npx skills add okx/plugin-store --skill "${DAPP_LOWER}-plugin" --yes --global 2>/dev/null; then TARGET_PLUGIN="${DAPP_LOWER}-plugin" else TARGET_PLUGIN="" fi fi ``` ### Technical Analysis For DApps outside the fixed resolver table, the Skill treats membership in the current GitHub directory listing as sufficient authorization to install and load a plugin. The API response comes from a mutable repository branch and is not tied to an audited commit, signed manifest, checksum, or local allowlist. When exactly one prefix match exists, the Skill immediately performs a silent global installation and directs the Agent to read the plugin's instructions. If the API cannot be reached or parsed, it falls back to attempting i ...[truncated 1857 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the mutable live catalog with a local allowlist containing reviewed plugin identifiers and immutable revisions. 2. If catalog discovery is required, retrieve a signed manifest and verify its signature before using any result. 3. Resolve repository contents against a pinned commit SHA rather than the default branch. 4. Do not install a catalog match automatically. Present the exact plugin, publisher, revision, requested permissions, and source files for explicit approval. 5. Download unknown plugins into a non-executable quarantine directory and audit all instructions and scripts before activation. 6. Verify every file against trusted hashes and reject plugins containing unapproved shell execution, binary downloads, PATH modifications, or broad filesystem access. 7. Remove the clone-and-install fallback. A failed availability check must fail closed rather than becoming an installation attempt. 8. Run approved plugins in a restricted sandbox with narrowly scoped filesystem, network, wallet, and credential access. 9. Maintain revocation metadata so compromised plugin revisions can be blocked even if they remain present upstream. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:367
Finding
User-Controlled DApp Name Is Used as an Unescaped Regular Expression and Shell Template Value<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 367-380 **Vulnerability Type**: Insufficient validation of user-derived shell and regular-expression input **Risk Level**: Medium ### Complete Code Snippet ```bash # Normalize the user-named DApp to a plugin-store-style ID prefix (lowercase, no dots) DAPP_LOWER=$(echo "<DApp name as user typed it>" | tr 'A-Z' 'a-z' | tr -d '.') # Fast catalog probe via GitHub Contents API (~0.1s) CATALOG=$(curl -fsSL --max-time 5 "https://api.github.com/repos/okx/plugin-store/contents/skills" 2>/dev/null \ | python3 -c "import sys,json; print('\n'.join(p['name'] for p in json.load(sys.stdin)))" 2>/dev/null) if [ -n "$CATALOG" ]; then # Prefix match — handles -plugin, -ai, and -v2-plugin MATCHES=$(echo "$CATALOG" | grep -E "^${DAPP_LOWER}(-|$)" || true) COUNT=$(echo "$MATCHES" | grep -c . 2>/dev/null || echo 0) ``` ### Technical Analysis The normalization step only lowercases ASCII letters and removes periods. It does not reject shell metacharacters, whitespace, control characters, or regular-expression operators. `DAPP_LOWER` is then interpolated into an extended regular expression: ```bash grep -E "^${DAPP_LOWER}(-|$)" ``` Characters such as `[](){}|+*?^$` can change the expression's meaning. A crafted DApp name may therefore match an unintended catalog entry, broaden the result set, or cause matching errors. The document also uses a textual placeholder inside a shell command: ```bash echo "<DApp name as user typed it>" ``` If an Agent implements this instruction by directly constructing shell source from the user text, command substitutions or quoting characters may be interpreted by the shell. If the value is instead passed as already-bound data, direct shell command injection is less likely; however, the regular-expression injection remains because the variable is deliberately interpreted as regex syntax. ### Attack Path 1. An attacker supplies a DApp name containing extende ...[truncated 1216 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Accept only a strict plugin-name character set after normalization, such as: ```text ^[a-z0-9][a-z0-9_-]{0,63}$ ``` Reject all other input rather than attempting to sanitize it. 2. Never substitute user text directly into generated shell source. 3. Pass input as data through positional arguments or environment variables and use `printf '%s\n'` instead of `echo`. 4. Replace `grep -E` with literal comparison. For example, parse the JSON in Python and compare normalized strings using `name == prefix` or `name.startswith(prefix + "-")`. 5. If a regular expression is unavoidable, escape the user-derived value with a proven regex-escaping function before interpolation. 6. Keep the catalog-to-plugin mapping separate from the user's raw prompt and require the selected value to exist in a trusted allowlist. 7. Fail closed on invalid input, ambiguous results, API failures, or parsing errors. Do not convert any of these conditions into an automatic installation attempt. 8. Add tests for spaces, quotes, command substitutions, newlines, regex operators, Unicode confusables, leading hyphens, and excessively long names. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
Findings (22)

Memory Manipulation

High
Category
Memory Poisoning
Content
### PancakeSwap V3 CLMM → `pancakeswap-clmm-plugin`

**Keywords that raise confidence ≥ 75:**
PancakeSwap V3 CLMM, PancakeSwap CLMM, V3 LP NFT (in PancakeSwap context), concentrated liquidity on PancakeSwap, V3 fee tier (with PCS), PancakeSwap V3 farm, 薄饼 CLMM, 薄饼 集中流动性.

**Default-resolution rule:** plain "PancakeSwap" or "PancakeSwap V3" without CLMM / concentrated / LP NFT signals → `pancakeswap-v3-plugin` (AMM), NOT this plugin.
Confidence
85% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
### PancakeSwap V3 CLMM → `pancakeswap-clmm-plugin`

**Keywords that raise confidence ≥ 75:**
PancakeSwap V3 CLMM, PancakeSwap CLMM, V3 LP NFT (in PancakeSwap context), concentrated liquidity on PancakeSwap, V3 fee tier (with PCS), PancakeSwap V3 farm, 薄饼 CLMM, 薄饼 集中流动性.

**Default-resolution rule:** plain "PancakeSwap" or "PancakeSwap V3" without CLMM / concentrated / LP NFT signals → `pancakeswap-v3-plugin` (AMM), NOT this plugin.
Confidence
85% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Self-Modification

High
Category
Rogue Agent
Content
- Some: `<name>-v2-plugin` (e.g. `velodrome-v2-plugin`)
- Some: bare names (e.g. `meme-trench-scanner`, `top-rank-tokens-sniper`)

A strict `${DAPP_LOWER}-plugin` exact match would miss `uniswap-ai` and `velodrome-v2-plugin`. The prefix-match approach against the live catalog catches all three suffix conventions automatically — no need to update this skill every time a new plugin lands with a different naming style.

**Why this design:** `npx skills` has no `info` / `search` / `exists` subcommand today. The only catalog enumeration verb is `add --list`, which clones the whole repo and prints all entries — slow and over-broad. The GitHub Contents API gives a deterministic, ~0.1s "exists or not" check directly. The fallback to `npx skills add` preserves correctness when the API is unreachable.
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The skill repeatedly invokes `npx skills` without pinning an exact package version or integrity-verified source. That allows supply-chain drift: a newer or compromised package release could change behavior and execute arbitrary code in the agent context during listing or installation.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
This unpinned `npx skills` invocation performs runtime package resolution from an external ecosystem without version locking. In an agent skill that can trigger installs and command execution, that creates meaningful supply-chain risk if the package or one of its dependencies is updated maliciously or unexpectedly.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
Here the unpinned `npx skills add` path is especially risky because it installs code, not just lists metadata. A compromised upstream package or changed CLI behavior could lead to arbitrary code execution and unreviewed plugin installation with global scope.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly instructs silent global plugin installation without prior user confirmation. Because installing a plugin changes the agent's capabilities and may execute additional code or pre-flight steps, doing so transparently bypasses informed consent and can expose the environment to unreviewed code.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The skill instructs runtime use of `npx skills` for catalog probing and installation decisions without version control. Because this router is designed to forward user prompts into newly installed plugins, any supply-chain compromise can propagate directly into sensitive trading or wallet-adjacent workflows.

External Transmission

Medium
Category
Data Exfiltration
Content
DAPP_LOWER=$(echo "<DApp name as user typed it>" | tr 'A-Z' 'a-z' | tr -d '.')

# Fast catalog probe via GitHub Contents API (~0.1s)
CATALOG=$(curl -fsSL --max-time 5 "https://api.github.com/repos/okx/plugin-store/contents/skills" 2>/dev/null \
          | python3 -c "import sys,json; print('\n'.join(p['name'] for p in json.load(sys.stdin)))" 2>/dev/null)

if [ -n "$CATALOG" ]; then
Confidence
90% confidence
Finding
The skill sends data to the GitHub Contents API as part of catalog probing. Although the transmitted content is limited, it still creates external disclosure of user-request-derived DApp names and environment behavior, and it couples routing to a third-party network dependency.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
This `npx skills add` invocation remains unpinned and is used in a branch that can auto-install a matched plugin. Even if intended as a fallback, it still trusts mutable external package resolution at runtime, which is inappropriate for a privileged plugin-management path.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding
This fallback uses unpinned `npx skills add` together with guessed plugin naming, compounding supply-chain and incorrect-install risk. The agent may end up executing code from an unintended or compromised package path under global install semantics.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The fallback path silently installs a guessed plugin name when the GitHub API is unreachable. That is dangerous because a network failure or catalog ambiguity can lead directly to installing unintended code globally, without notice or confirmation.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
These references describe `npx skills` limitations, but they still normalize use of an unpinned external CLI throughout the skill. In context, the actual danger comes from the executable invocations elsewhere rather than the explanatory prose itself.

External Transmission

Medium
Category
Data Exfiltration
Content
> - The `python3 -c` parse of the GitHub Contents API response assumes Python 3 is on PATH (Python 3 ships by default on macOS 10.15+ / all common Linux distros / Windows-Git-Bash with Python). If `python3` is missing, substitute `jq` — full one-liner:
>
>   ```bash
>   CATALOG=$(curl -fsSL --max-time 5 "https://api.github.com/repos/okx/plugin-store/contents/skills" 2>/dev/null \
>             | jq -r '.[].name' 2>/dev/null)
>   ```
>
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The failure-mode guidance includes another unpinned `npx skills add` command for manual recovery. That extends the same supply-chain risk to users/operators and can normalize insecure remediation under failure conditions.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
This line continues the same insecure recovery guidance by directing use of a floating `npx skills` command. In security-sensitive plugin-routing workflows, unsafe operational guidance is still a real weakness because it encourages privileged execution of mutable external code.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
> *(Path is Claude Code-specific — see Known Limitations in Step 1. On Codex / OpenCode / OpenClaw / Cursor, substitute the equivalent skills directory for your agent.)*

Then **immediately re-apply the user's original request** using the plugin's own routing — do not ask the user to repeat themselves. Do not show an install banner or onboarding table.

**Rule 2 — Not installed, exactly one DApp scores ≥ 75:**
Install silently, then load and execute:
Confidence
88% confidence
Finding
The skill is designed to autonomously re-apply the user's request through another plugin without re-confirmation, reducing human oversight at the handoff point. In isolation that can be convenient, but here it compounds the risk from dynamic plugin installation and delegated financial actions.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
Rule 2 formally requires silent installation, loading, and execution of a plugin whenever one match scores highly. In this skill context, that means a user utterance can trigger installation of third-party DeFi tooling and subsequent command execution without an explicit consent boundary, which is especially risky around financial operations.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
At this core execution point, the skill directs silent install-and-execute behavior through unpinned `npx skills add`. The combination of floating dependency resolution, global installation, and subsequent prompt forwarding substantially increases the chance of arbitrary code execution or hostile plugin behavior.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
This occurrence is part of failure-mode documentation rather than a new execution path, so its direct risk is lower. However, it still reinforces unsafe use of unpinned runtime tooling in a context where plugins may perform sensitive actions.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
Like the other documentation instances, this line is not independently exploitable but contributes to an insecure operational pattern. In aggregate with the executable commands above, it supports a genuine supply-chain weakness.

External Script Fetching

Low
Category
Supply Chain
Content
DAPP_LOWER=$(echo "<DApp name as user typed it>" | tr 'A-Z' 'a-z' | tr -d '.')

# Fast catalog probe via GitHub Contents API (~0.1s)
CATALOG=$(curl -fsSL --max-time 5 "https://api.github.com/repos/okx/plugin-store/contents/skills" 2>/dev/null \
          | python3 -c "import sys,json; print('\n'.join(p['name'] for p in json.load(sys.stdin)))" 2>/dev/null)

if [ -n "$CATALOG" ]; then
Confidence
15% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Static analysis

No suspicious patterns detected.