Back to skill

Security audit

minecraft-bridge

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Minecraft bot bridge, but it exposes unauthenticated local control with a raw slash-command endpoint that can affect a server if the bot is privileged.

Install only if you are comfortable running a local Minecraft bot-control service. Use a non-operator bot account, do not expose the bridge port, stop the bridge when finished, and avoid using POST /command except in worlds where server-changing commands are acceptable. Review or pin npm dependencies before routine use.

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

T09 · Insecure Skill Coding Practices

Error
Location
bridge-server.js:325
Finding

Unauthenticated Local API Permits Privileged Minecraft Bot Control

Content
View full analysis
{ if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; } let body = ''; let bodyBytes = 0; req.on('data', c => { bodyBytes += c.length; if (bodyBytes > MAX_BODY_BYTES) { json(res, 413, { success: false, error: 'Request body too large' }); req.destroy(); return; } body += c; }); req.on('end', async () => { const url = req.url.split('?')[0]; const qs = Object.fromEntries(new URLSearchParams(req.url.split('?')[1] || '')); const key = `${req.method} ${url}`; const handler = handlers[key]; if (!handler) { json(res, 404, { error: 'Unknown route', available: Object.keys(handlers) }); return; } if (key !== 'GET /status' && !requireConnected(res)) return; try { const parsed = body ? JSON.parse(body) : {}; const result = await handler(parsed, qs); json(res, 200, { success: true, ...result }); } catch (err) { console.error(`[bridge] ${key} error:`, err.message); json(res, 500, { success: false, error: err.message }); } }); }); server.listen(CFG.bridge.port, '127.0.0.1', () => { ``` ### Technical Analysis The HTTP server dispatches requests solely according to the HTTP method and path. It does not require an authentication token, validate caller identity, or perform authorization checks for high-impact endpoints. Binding to `127.0.0.1` reduces direct remote exposure but is not an authentication boundary. Any process running in the same network namespace can access the API. The service may also become reachable through local proxies, port forwarding, browser-to-localhost attack techniques, or server-side request forgery in another local application. The exposed ...[truncated 1204 chars]
Remediation
View remediation
` header on every endpoint, including state-reading endpoints where confidentiality matters. 3. Compare credentials using a timing-safe operation. 4. Store the token in a user-private file with mode `0600`, preferably below a directory with mode `0700`. 5. Return HTTP 401 for missing or invalid credentials and HTTP 403 for unauthorized operations. 6. Separate read-only and action privileges if multiple clients need access. 7. Continue binding exclusively to loopback and explicitly reject non-loopback clients. 8. Document that reverse proxies, container port publication, SSH forwarding, and public exposure require an additional authenticated security layer. 9. Run the Minecraft bot with the minimum server permissions required for its intended tasks. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
bridge-server.js:191
Finding

Slash-Command Safety Denylist Can Be Bypassed

Content
View full analysis
{ if (!command) throw new Error('command field required'); const BLOCKED_COMMANDS = /^\/?(?:op|deop|stop|ban|ban-ip|pardon|kick|whitelist|save-off|save-all|save-on|reload|restart)\b/i; if (BLOCKED_COMMANDS.test(command.trim())) { throw new Error(`Command blocked for safety: "${command}". Use minecraft-server-admin / RCON for server administration.`); } const cmd = command.startsWith('/') ? command : `/${command}`; state.bot.chat(cmd); return { executed: cmd }; }, ``` ### Technical Analysis The endpoint forwards arbitrary slash commands and attempts to protect dangerous operations using a small regular-expression denylist. Denylists are unsuitable for enforcing command security because Minecraft servers may support: - Namespaced commands, such as commands prefixed with `minecraft:`. - Wrapper or nested-command mechanisms. - Aliases and plugin-defined commands. - Dangerous built-in commands not included in the regular expression. - Future commands added by server updates or plugins. The check only examines the beginning of the supplied string and does not parse command syntax or recursively inspect nested commands. Consequently, a semantically equivalent command may avoid matching the blocked command name. This weakness is compounded by the lack of API authentication. ### Attack Path 1. The attacker gains access to the local bridge API. 2. The attacker identifies a privileged command that is absent from the denylist or a namespaced, aliased, plugin-defined, or nested equivalent of a blocked command. 3. The attacker submits it in the `command` property of a request to `POST /command`. 4. The regular expression does not recognize the effective privileged operation. 5. The bridge pref ...[truncated 741 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/start.sh:17
Finding

Runtime Installation Uses Unpinned npm Dependencies

Content
View full analysis
/dev/null; then echo "Installing bridge dependencies..." cd "$SKILL_DIR" && npm install mineflayer mineflayer-pathfinder vec3 --silent fi ``` Related dependency declarations do not specify versions: ```yaml install: - id: mineflayer kind: node package: mineflayer label: "Mineflayer — Minecraft bot API" - id: mineflayer-pathfinder kind: node package: mineflayer-pathfinder label: "Pathfinder — navigation plugin" - id: vec3 kind: node package: vec3 label: "Vec3 — 3D coordinate helper" ``` ### Technical Analysis The startup script invokes `npm install` with bare package names. No exact versions, lockfile, or integrity values are present in the audited project. As a result, installation results may change over time and may include newly released transitive dependencies. npm installation may also execute package lifecycle scripts with the privileges of the user starting the bridge. Although the package names appear consistent with the documented functionality and no malicious dependency was confirmed, this installation design unnecessarily expands supply-chain risk. The dependency check only tests whether `mineflayer` can be required. It does not verify the installed versions or integrity of any of the three dependencies. ### Attack Path 1. A direct or transitive dependency publishes a compromised release, or its registry account or distribution process is compromised. 2. A user runs `scripts/start.sh` on a system where `mineflayer` is not currently resolvable. 3. The script runs `npm install` without a lockfile or exact versions. 4. npm resolves the current package graph and downloads the compromised component. 5. Malicious lifecycle cod ...[truncated 536 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/start.sh:28
Finding

Predictable Shared Temporary Files Permit Symlink-Based File Clobbering

Content
View full analysis
/tmp/minecraft-bridge.log 2>&1 & ``` The documented health-check pattern also uses a fixed shared path: ```bash BRIDGE_PORT="${MC_BRIDGE_PORT:-3001}" BRIDGE_URL="http://localhost:${BRIDGE_PORT}" check_bridge() { if ! curl -sf "${BRIDGE_URL}/status" > /tmp/mc_status.json 2>/dev/null; then echo "ERROR:NOT_RUNNING" return 1 fi local connected connected=$(python3 -c "import json; print(json.load(open('/tmp/mc_status.json')).get('connected', False))" 2>/dev/null) if [ "$connected" != "True" ] && [ "$connected" != "true" ]; then echo "ERROR:BOT_OFFLINE" return 2 fi echo "OK" return 0 } ``` ### Technical Analysis Both paths are predictable and located directly under `/tmp`, which is commonly writable by all local users. Shell redirection opens the named path without securely creating a new file and without verifying that the path is a regular file owned by the current user. A local attacker may pre-create one of these paths as a symbolic link to another file writable by the victim. When the victim starts the bridge or runs the documented health check, shell redirection follows the link and truncates or overwrites the link target. The shared `mc_status.json` name also permits race conditions and status-response spoofing between concurrent users or processes. ### Attack Path 1. A local attacker predicts that the victim will run `start.sh` or use the documented shell health check. 2. The attacker creates `/tmp/minecraft-bridge.log` or `/tmp/mc_status.json` as a symbolic link to a file writable by the victim. 3. The victim runs the corresponding command. 4. Shell output redirection follo ...[truncated 813 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/stop.sh:3
Finding

Fallback Shutdown Logic Can Terminate Unrelated Processes

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 120)May include surrounding context.

md
See `references/api-spec.md` for the full schema.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 155)May include surrounding context.

md
See `references/api-spec.md` for the full schema.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The API is explicitly unauthenticated and exposes powerful bot-control functionality on localhost, including arbitrary command execution elsewhere in the spec. Localhost is not a security boundary against malicious local software, browser-assisted attacks in some environments, or unintended cross-tool invocation, so the lack of authentication materially increases the risk of unauthorized game and potentially server-impacting actions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises shell execution and environment-variable usage but does not declare an explicit tool scope such as permissions or allowed-tools. That weakens least-privilege controls and can let the agent invoke broader local capabilities than reviewers or users would expect, especially because the instructions include running Node and curl commands against a local service. In this context the bridge is meant for live local bot control, so shell/env access is somewhat expected, but the lack of explicit scoping still increases risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill exposes or documents a /command path that forwards arbitrary slash commands to Minecraft. If the bot has operator privileges, command-block-like access, or is on a permissive server, this can be used for destructive administration actions, griefing, teleportation, inventory manipulation, or broader server impact unrelated to the skill's core movement/mining/crafting purpose. The skill context makes this more dangerous because it is a live-control bridge, so arbitrary command forwarding materially expands authority beyond normal bot actions.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · config.example.json (reported line 9)May include surrounding context.

json
"MC_BRIDGE_PORT": "3001",
  "MC_VERSION": "1.21.1",
  "MC_AUTH": "offline",
  "_auth_note": "Use MC_AUTH=offline for local/offline servers; use MC_AUTH=microsoft for authenticated servers.",
  "_port_note": "For singleplayer, use ESC -> Open to LAN and copy the random port into MC_PORT."
}

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documented /command endpoint allows arbitrary slash-command execution through the bot, which exceeds narrowly scoped movement/inventory/live-control actions and can invoke powerful server-side capabilities if the bot has permissions. Because the API is unauthenticated and intended for easy local use, any local process or prompt-induced action that reaches this bridge could trigger destructive or privilege-bearing commands.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Although the spec notes that /command is 'potentially high risk,' it does not clearly warn about concrete destructive outcomes such as item spawning, player punishment, griefing, teleportation, or broader server administration if the bot is privileged. This under-communicates the danger to integrators and increases the chance the endpoint will be used casually in unsafe contexts.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% 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.

Content

Scanner excerpt · scripts/start.sh (reported line 28)May include surrounding context.

sh
echo "  API port: $BRIDGE_PORT"
echo ""

nohup node "$SKILL_DIR/bridge-server.js" > /tmp/minecraft-bridge.log 2>&1 &
echo $! > "$PID_FILE"

for i in $(seq 1 10); do

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file includes a troubleshooting command to run DEBUG=mineflayer:* node bridge-server.js, which can produce extensive internal logs. The surrounding text does not warn users that verbose debug output may include connection, environment, or gameplay/session details that should be handled carefully.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.