T08 · Insecure Dependencies
- Location
references/mcp-adapter-guide.md:27- Finding
Mutable GitHub releases and development branches are installed as executable WordPress plugins
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent WordPress MCP setup purpose, but its scripts and references handle credentials, agent configuration, and remote plugin installs in ways that require careful review before use.
Install only if you are comfortable reviewing and manually controlling the high-trust steps. Use dry-run first, pin exact plugin and npm versions, require checksums, use HTTPS only, avoid passing secrets on command lines, prefer least-privileged WordPress service accounts, and review any changes to local MCP client configuration before restarting agents.
references/mcp-adapter-guide.md:27Mutable GitHub releases and development branches are installed as executable WordPress plugins
references/mcp-adapter-guide.md:197Unpinned npm proxy is automatically downloaded and executed with WordPress credentials
scripts/install_wp_plugin.sh:127Plugin installer treats a missing checksum as successful verification
scripts/setup_wordpress_mcp.sh:39WordPress credentials are accepted as command-line arguments and may be sent over unencrypted HTTP
scripts/setup_wordpress_mcp.sh:220Unescaped WordPress URL permits TOML configuration injection
references/troubleshooting.md:230Troubleshooting commands disclose existing and newly generated bearer tokens
Normalizing --allow-root in a skill that already performs plugin installs, option updates, and filesystem actions is dangerous because it suppresses WP-CLI's safety boundary against root execution. If an agent follows this pattern broadly, mistakes or injected paths can have full-system or full-site impact rather than being confined to the web user context.
/www/server/php/<version>/ (e.g. /www/server/php/85/)/www/wwwroot/<domain>/www:www--allow-root and the right PHP binary# aaPanel example — run as the web user, not root, when possible
This line installs a plugin while explicitly permitting root execution, bypassing WP-CLI's defense-in-depth check. In practice, that means an agent could write executable PHP into the site with maximal privileges, magnifying the consequences of any path error, compromised package, or prompt-influenced command construction.
curl -fsSL -o /tmp/mcp-adapter.zip "https://github.com/WordPress/mcp-adapter/releases/download/${MCP_ADAPTER_VERSION}/mcp-adapter.zip"
sudo -u www cp /tmp/mcp-adapter.zip "$WP_PATH/wp-content/upgrade/" sudo -u www wp plugin install "$WP_PATH/wp-content/upgrade/mcp-adapter.zip" --activate --path="$WP_PATH" --allow-root sudo -u www wp rewrite flush --path="$WP_PATH" --allow-root
Although wp rewrite flush is less dangerous than installation, pairing it with --allow-root still weakens execution safeguards and normalizes unsafe defaults. This contributes to a broader privileged-execution anti-pattern in the skill.
sudo -u www cp /tmp/mcp-adapter.zip "$WP_PATH/wp-content/upgrade/" sudo -u www wp plugin install "$WP_PATH/wp-content/upgrade/mcp-adapter.zip" --activate --path="$WP_PATH" --allow-root sudo -u www wp rewrite flush --path="$WP_PATH" --allow-root
## A.2 Enable Application Passwords
Listing admin users with --allow-root needlessly performs a sensitive identity enumeration action under elevated trust. In an agent context, this can facilitate subsequent privileged credential creation or user targeting while bypassing built-in safeguards.
# List admin users
wp user list --role=administrator --fields=ID,user_login --allow-root --path="$WP_PATH"
# Create application password for a chosen admin user (replace <USER_ID>)
# The generated password is printed once; capture it securely and do not log it.
Creating an application password under --allow-root is particularly risky because it generates long-lived API credentials while bypassing WP-CLI's root-safety restriction. If abused, it can grant persistent administrative API access to a WordPress site under the control of an automated agent.
wp user application-password create <USER_ID> "mcp-clients" --allow-root --path="$WP_PATH"
> **Store the password securely.** It is shown only once. The full credential for Basic Auth is `base64("username:password")`. Never write the password to the console log, to a committed file, or to an untrusted client.
Installing ai-engine with --allow-root combines remote package retrieval and plugin activation with elevated execution semantics. Because plugins execute PHP on the server, this materially increases the impact of supply-chain compromise or operator error.
# Use a pinned version (replace <VERSION> with the desired release, e.g. "4.2.0")
AI_ENGINE_VERSION="<VERSION>"
wp plugin install "ai-engine.${AI_ENGINE_VERSION}" --activate --allow-root --path="$WP_PATH"
# If wp plugin install fails (some hosts block remote installs):
# 1. Download manually from https://wordpress.org/plugins/ai-engine/ (specific version)
This line runs wp eval with --allow-root, which is effectively arbitrary PHP execution with elevated trust on the WordPress host. Even though the example is for enabling a module and setting a token, the pattern is dangerous because any modification or injection would execute server-side code directly.
$o["mcp_bearer_token"] = "'"$TOKEN"'"; update_option("mwai_options", $o); echo "module_mcp enabled\n"; ' --allow-root --path="$WP_PATH"
wp rewrite flush --allow-root --path="$WP_PATH"
Using --allow-root for rewrite flushing continues the unsafe privileged-execution model immediately after arbitrary option modification. While the specific command is routine, the pattern reduces safety barriers in a high-trust automation workflow.
echo "module_mcp enabled\n"; ' --allow-root --path="$WP_PATH"
wp rewrite flush --allow-root --path="$WP_PATH"
> **Store the token securely.** It is the only credential needed for the AI Engine MCP endpoint. Never commit or log it.
Even though commented, this example encourages enabling highly sensitive AI Engine features via wp eval ... --allow-root, including SQL execution and plugin/theme actions. The combination of arbitrary PHP and root-tolerant execution can quickly become a route to full site compromise if copied into practice.
## B.3 The MCP endpoint
The skill includes detailed MCP configuration locations and schema guidance, which enables automated modification of agent connection settings. In combination with shell/file-write capability, this becomes a real security issue because it can be used to install or alter trusted remote endpoints and auth headers.
| Platform | Config file | Root key | URL field | Gotcha |
|----------|-------------|----------|-----------|--------|
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `devin mcp add` CLI |
| OpenCode | `~/.config/opencode/opencode.json` | `mcp` | `url` | `type: "remote"`, `environment` not `env` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | `httpUrl` | NOT `url`! |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | `httpUrl` | NOT `url`! |
The skill provides instructions to access and modify agent configuration files in user home directories, including MCP settings that may contain credentials or trusted server definitions. In an agent environment, writing these files can create persistence, redirect tool traffic, or silently add malicious endpoints.
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `devin mcp add` CLI |
| OpenCode | `~/.config/opencode/opencode.json` | `mcp` | `url` | `type: "remote"`, `environment` not `env` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | `httpUrl` | NOT `url`! |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | `httpUrl` | NOT `url`! |
| Codex | `~/.codex/config.toml` | `[mcp_servers.<name>]` | `url` | Headers in sub-table |
| OpenClaw | `~/.openclaw/openclaw.json` | `mcp.servers` | `url` | `openclaw mcp add` CLI |
Referencing and potentially altering ~/.codex/config.toml exposes a high-value persistence surface for agent behavior and authentication headers. If misused or automated without strict confirmation, this can modify trusted MCP endpoints or inject attacker-controlled configuration.
| OpenCode | `~/.config/opencode/opencode.json` | `mcp` | `url` | `type: "remote"`, `environment` not `env` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | `httpUrl` | NOT `url`! |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | `httpUrl` | NOT `url`! |
| Codex | `~/.codex/config.toml` | `[mcp_servers.<name>]` | `url` | Headers in sub-table |
| OpenClaw | `~/.openclaw/openclaw.json` | `mcp.servers` | `url` | `openclaw mcp add` CLI |
> **Top 3 silent-failure traps:**
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.
| mcp-adapter tools/list empty | Missing `Mcp-Session-Id` header | Capture from `initialize` response headers, send in subsequent requests |
| AI Engine endpoint 404 | `module_mcp` is `false` | `wp eval '$o=get_option("mwai_options"); $o["module_mcp"]=true; update_option("mwai_options",$o);'` |
| AI Engine 401 Unauthorized | Wrong or missing Bearer Token | Check `mwai_options.mcp_bearer_token`; re-generate if needed |
| `composer install` fails | Composer < 2.2 (jetpack-autoloader requires ^2.2) | `composer self-update --2` |
| `wp plugin install ai-engine` fails | Host blocks WP.org downloads | Download zip manually, extract, copy to `wp-content/plugins/` |
| MCP config silently ignored (no tools) | Wrong field name for platform | See `references/platform-quirks.md` (httpUrl vs url, mcp vs mcpServers) |
| Gemini CLI MCP not loading | Used `url` instead of `httpUrl` | Gemini uses `httpUrl` for HTTP servers, not `url` |
Referenced artifact was not completely inspected
- **`scripts/setup_wordpress_mcp.sh`** — Detects all installed MCP clients and patches each with the correct format.
Exposing SQL execution through MCP is highly dangerous and not justified by a setup/troubleshooting skill. If available to an agent, it can bypass higher-level WordPress permission checks and directly read, modify, or destroy site data, including credentials, tokens, content, and configuration.
The dynamic REST feature can expose arbitrary custom endpoints as MCP tools, significantly expanding the reachable attack surface beyond the stated purpose. This can unintentionally grant agents access to sensitive or unsafe application functionality that was never reviewed for AI-mediated invocation.
The documentation includes wp eval ... --allow-root, which encourages running a powerful interpreter as root. In practice this can normalize unsafe operational habits, reduce guardrails, and increase the blast radius of mistakes or abuse when modifying WordPress options that control MCP feature exposure.
// $o["mcp_feature_social_engine"] = true; // $o["mcp_feature_dynamic_rest"] = true; update_option("mwai_options", $o); ' --path=$WP_PATH --allow-root
---
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
URL="https://yourdomain.com/wp-json/mcp/v1/http"
# List all available tools (names + descriptions)
curl -s -X POST "$URL" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
The documentation creates an application password for user ID 1 with --allow-root, and the surrounding examples imply using the admin account for MCP access. In the context of exposing WordPress abilities remotely, encouraging credentials tied to a highly privileged account amplifies the impact of any secret leakage or misuse, potentially granting broad administrative access through Basic Auth.
wp eval 'echo wp_is_application_passwords_available() ? "enabled" : "disabled";' --path=$WP_PATH --allow-root
# Create application password
wp user application-password create 1 "mcp-clients" --path=$WP_PATH --allow-root
# Output: Password: xxxx xxxx xxxx xxxx xxxx xxxx
# Generate Basic Auth value
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.
| Command | Description |
|---------|-------------|
| `wp mcp-adapter serve [--server=<id>] [--user=<user>]` | Serve MCP server via STDIO |
| `wp mcp-adapter list [--format=<format>]` | List all MCP servers |
### Examples
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.
| Platform | Config file | Root key | Remote URL field | Auth field | Transport marker |
|----------|-------------|----------|------------------|------------|------------------|
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `headers` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `headers` | — (HTTP auto-detected) |
| OpenCode | `~/.config/opencode/opencode.json` | **`mcp`** | `url` | `headers` | `type: "remote"` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.
| Platform | Config file | Root key | Remote URL field | Auth field | Transport marker |
|----------|-------------|----------|------------------|------------|------------------|
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `headers` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `headers` | — (HTTP auto-detected) |
| OpenCode | `~/.config/opencode/opencode.json` | **`mcp`** | `url` | `headers` | `type: "remote"` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `headers` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `headers` | — (HTTP auto-detected) |
| OpenCode | `~/.config/opencode/opencode.json` | **`mcp`** | `url` | `headers` | `type: "remote"` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| Codex | `~/.codex/config.toml` | `[mcp_servers.<name>]` | `url` | **sub-table `headers`** | — |
| OpenClaw | `~/.openclaw/openclaw.json` | `mcp.servers` | `url` | `--header` flag | `transport: "streamable-http"` |
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `headers` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `headers` | — (HTTP auto-detected) |
| OpenCode | `~/.config/opencode/opencode.json` | **`mcp`** | `url` | `headers` | `type: "remote"` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| Codex | `~/.codex/config.toml` | `[mcp_servers.<name>]` | `url` | **sub-table `headers`** | — |
| OpenClaw | `~/.openclaw/openclaw.json` | `mcp.servers` | `url` | `--header` flag | `transport: "streamable-http"` |
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
| Claude Code | `~/.claude.json` | `mcpServers` | `url` | `headers` | `type: "http"` |
| Devin CLI | `~/.config/devin/mcp_config.json` | `mcpServers` | `url` | `headers` | — (HTTP auto-detected) |
| OpenCode | `~/.config/opencode/opencode.json` | **`mcp`** | `url` | `headers` | `type: "remote"` |
| Gemini CLI | `~/.gemini/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| AGY | `~/.gemini/antigravity-cli/settings.json` | `mcpServers` | **`httpUrl`** | `headers` | — |
| Codex | `~/.codex/config.toml` | `[mcp_servers.<name>]` | `url` | **sub-table `headers`** | — |
| OpenClaw | `~/.openclaw/openclaw.json` | `mcp.servers` | `url` | `--header` flag | `transport: "streamable-http"` |