Back to skill

Security audit

agent mcp bridge

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to build a local agent message bridge, but it under-scopes authentication, persistence, and dependency risks enough that users should review it carefully before installing.

Install only if you intentionally need a local inter-agent bridge on a trusted single-user machine. Prefer running the server on demand instead of loading the LaunchAgent, avoid sending secrets through the bridge, pin and review dependencies before installation, and add authentication or strict agent identity validation before allowing agents to auto-process messages.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T06 · System Persistence

Error
Location
references/launchd-plist.md:17
Finding

Persistent Launch Agent Runs the Broker Across User Sessions

Content
View full analysis
/references/launchd-plist.md ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist # Edit the plist to set correct paths, then: launchctl load ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist ``` From `references/launchd-plist.md:17-21`: ```xml RunAtLoad KeepAlive ``` ### Technical Analysis The documented installation creates and loads a macOS per-user launch agent. `RunAtLoad` starts the broker automatically when the launch agent is loaded or the user logs in, while `KeepAlive` causes launchd to restart it after termination. This behavior survives the original Skill invocation and is not required for the broker's fundamental functionality. The server can instead be started on demand when inter-agent communication is needed. Continuous persistence therefore exceeds the minimum operational requirement. The launch agent executes Python and server files from a user-writable directory under `~/.openclaw/agent-bridge-mcp`. Any subsequent unauthorized modification of those files or their virtual environment would be executed automatically by launchd. ### Attack Path 1. The user follows the Skill instructions and copies the plist into `~/Library/LaunchAgents`. 2. The user edits the paths and invokes `launchctl load`. 3. launchd starts the broker and retains its registration across sessions. 4. The service is restarted automatically because `KeepAlive` is enabled. 5. If the broker script, interpreter, or virtual environment is subsequently replaced or modified, the altered code executes automatically under the user's account. ### Impact Assessment The service obtains persistent code execution with the privileges of the affected macOS user. It does not obtain ro ...[truncated 234 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/server/server.py:44
Finding

Unauthenticated Broker Permits Agent Spoofing, Message Disclosure, and Instruction Injection

Content
View full analysis
dict: """ Send a message from one agent to another. Returns the message_id of the sent message. """ message_id = str(uuid.uuid4())[:8] ts = datetime.now(timezone.utc).isoformat() thread_id = reply_to or message_id db = await get_db() try: await db.execute( "INSERT INTO messages VALUES (?,?,?,?,?,?,?,?,?)", (message_id, from_agent, to, subject, body, ts, thread_id, reply_to, "pending") ) await db.commit() finally: await db.close() return {"message_id": message_id, "timestamp": ts, "status": "sent"} @mcp.tool() async def poll_messages(agent_id: str, limit: int = 10) -> list: """ Poll for pending messages addressed to agent_id. Returns list of message dicts (oldest first). """ db = await get_db() try: cursor = await db.execute( "SELECT * FROM messages WHERE to_agent=? AND status='pending' ORDER BY timestamp ASC LIMIT ?", (agent_id, limit) ) rows = await cursor.fetchall() return [dict(row) for row in rows] finally: await db.close() @mcp.tool() async def mark_read(message_id: str) -> dict: """ Mark a message as read/processed. Returns success status. """ db = await get_db() try: await db.execute( "UPDATE messages SET status='read' WHERE id=?", (message_id,) ) await db.commit() return {"message_id": message_id, "status": "read"} finally: await d ...[truncated 3126 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/server/requirements.txt:1
Finding

Startup Installs Unbounded Third-Party Dependency Versions

Content
View full analysis
=2.0.0 uvicorn>=0.30.0 aiosqlite>=0.20.0 ``` ### Technical Analysis The startup script installs dependencies from the user's configured pip package index when the virtual environment does not exist. Each requirement specifies only a minimum version and permits arbitrary future releases. No cryptographic hashes or lock file are provided. Consequently, the source code reviewed in this project does not fully determine the code that will be downloaded and executed during installation or imported by the broker. The resulting environment can change over time without any change to the Skill package. This creates reproducibility, compatibility, and supply-chain risk. There is no evidence in the reviewed project that the named packages are intentionally malicious or typosquatted. The confirmed issue is the unsafe dependency resolution and installation policy. ### Attack Path 1. The user runs `start.sh` on a system where `.venv` does not yet exist. 2. The script creates the virtual environment and invokes pip. 3. pip contacts its configured package index and resolves the latest versions satisfying the lower bounds. 4. A compromised index, compromised package release, or maliciously altered package source can supply code that was not part of the audited project. 5. Package build or installation logic executes during installation, and imported package code executes when the server starts. 6. If the launchd setup is also enabled, the installed dependency code is subsequently loaded by the persistent servi ...[truncated 410 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/agent_bridge.py:27
Finding

Filesystem Bridge Trusts Unvalidated Agent Paths and Caller-Controlled File References

Content
View full analysis
str: """Write a message to the recipient's inbox. Returns message_id.""" message_id = str(uuid.uuid4())[:8] ts = datetime.now(timezone.utc).isoformat() msg = { "message_id": message_id, "from": self.agent_id, "to": to, "subject": subject, "body": body, "timestamp": ts, "thread_id": thread_id or message_id, "reply_to": reply_to, "status": "pending", } outbox = self.shared_dir / f"{to}-inbox" outbox.mkdir(parents=True, exist_ok=True) filename = f"{ts.replace(':', '-')}_{message_id}.json" (outbox / filename).write_text(json.dumps(msg, indent=2)) return message_id def receive(self) -> List[Dict[str, Any]]: """Read all pending messages from inbox. Returns list of message dicts.""" messages = [] for f in sorted(self.inbox.glob("*.json")): try: msg = json.loads(f.read_text()) msg["_file"] = str(f) messages.append(msg) except Exception: pass return messages def mark_pr ...[truncated 3039 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to set up an MCP broker and direct inter-agent messaging over MCP, but the visible instructions also rely on a filesystem bridge and heartbeat polling that operate through shared directories. This description-behavior mismatch is dangerous because users and orchestrating agents may trust it as a constrained local MCP integration while it actually introduces different communication and persistence mechanics with broader side effects.

Content

No source excerpt is available for this finding.

Possible Typosquatting: 'uvicorn' resembles popular package 'gunicorn'

High
Category
Supply Chain
Confidence
70% confidence
Finding

Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill instructs the agent to copy files into the user's home directory, modify OpenClaw configuration, and set up inbox/outbox paths, yet it declares no explicit tool scope or permissions. That mismatch can cause an agent runner to perform filesystem reads and writes without clear user-facing consent boundaries, increasing the risk of unintended local changes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger text is broad enough to activate on essentially any request involving agent-to-agent messaging, not just tightly scoped MCP broker setup. Overbroad activation can cause the skill to run in contexts the user did not intend, leading to unsolicited configuration changes, file creation, or persistence setup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The setup instructions direct copying files into ~/.openclaw, editing configuration, and using shared inbox/outbox directories, but they do not clearly warn the user that local files and configuration will be modified. Missing change-impact disclosure is risky because it undermines informed consent and can leave persistent artifacts or altered behavior on the host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The launchd instructions enable the broker to start automatically on login, creating persistent background execution, but the documentation does not explicitly warn the user about that persistence. Hidden or under-disclosed persistence is dangerous because it can keep an inter-agent communication service running indefinitely and expand the attack surface beyond the immediate session.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The reference to installing a plist under ~/Library/LaunchAgents indicates creation of a persistence mechanism for automatic execution. Even if intended for convenience, persistence is security-relevant because it survives the current session and can keep broker functionality available without repeated user approval.

Content

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

2. Register as a launchd service (macOS auto-start)

bash
cp <skill-dir>/references/launchd-plist.md ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist
# Edit the plist to set correct paths, then:
launchctl load ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Editing and deploying a launchd plist prepares a user-level autorun configuration, which constitutes session persistence. In the context of an agent communication bridge, that persistence may continuously expose a local IPC endpoint or background processing path after the initial setup is forgotten.

Content

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

bash
cp <skill-dir>/references/launchd-plist.md ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist
# Edit the plist to set correct paths, then:
launchctl load ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The same line also evidences use of a plist-backed LaunchAgent, reinforcing that the skill establishes session persistence rather than a one-time runtime-only process. In combination with local message brokering and shared-directory polling, persistence increases the chance of unintended continuous operation and message handling.

Content

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

bash
cp <skill-dir>/references/launchd-plist.md ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist
# Edit the plist to set correct paths, then:
launchctl load ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist

3. Add to OpenClaw config

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The same line also evidences use of a plist-backed LaunchAgent, reinforcing that the skill establishes session persistence rather than a one-time runtime-only process. In combination with local message brokering and shared-directory polling, persistence increases the chance of unintended continuous operation and message handling.

Content

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

bash
cp <skill-dir>/references/launchd-plist.md ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist
# Edit the plist to set correct paths, then:
launchctl load ~/Library/LaunchAgents/ai.openclaw.agent-bridge.plist

3. Add to OpenClaw config

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The documented fallback instructs two agents to exchange messages by reading and writing JSON files in a shared directory under the user's home folder. If those directories or files are created with permissive default permissions, any local process or co-tenant account with access could read, modify, inject, or replay agent messages, exposing sensitive data and undermining message integrity.

Content

Scanner excerpt · references/filesystem-bridge.md (reported line 3)May include surrounding context.

md
# Filesystem Bridge (Fallback)

Zero-infrastructure fallback when the MCP server is unavailable. Both agents read/write JSON files to a shared directory.

## Setup

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/launchd-plist.md (reported line 2)May include surrounding context.

md
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/launchd-plist.md (reported line 3)May include surrounding context.

md
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/launchd-plist.md (reported line 30)May include surrounding context.

md
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/launchd-plist.md (reported line 2)May include surrounding context.

md
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest describes setting up and using an MCP broker to enable direct communication between agents. However, the module docstring and implementation show a local shared-directory JSON file drop mechanism, with per-agent inbox folders and file moves, and no MCP protocol, broker process, or MCP client/server interaction.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file-level docstring explicitly says this is an 'Isaac/Hermes shared filesystem message bus' and demonstrates writing and reading local message files. That directly conflicts with the higher-level documented intent for the skill, which is to set up and use an MCP message broker for inter-agent communication.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency specification uses a lower-bound only constraint for fastmcp, which makes builds non-reproducible and allows future installs to silently pull in newer releases, including vulnerable or behavior-changing versions. In this skill's context, fastmcp is central to inter-agent communication and has a known history of security advisories, so leaving it unpinned increases supply-chain and exposure risk.

Content

Scanner excerpt · scripts/server/requirements.txt (reported line 1)May include surrounding context.

text
fastmcp>=2.0.0
uvicorn>=0.30.0
aiosqlite>=0.20.0

Unverifiable Dependency: fastmcp has 14 known advisory(ies) (CVE-2025-69196 (FastMCP OAuth Proxy token reuse across MCP servers); GHSA-c2jp-c369-7pvx (FastMCP Auth Integration Allows for Confused Deputy Account Takeover); CVE-2025-64340 (FastMCP has a Command Injection vulnerability - Gemini CLI) +11 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The manifest references fastmcp without pinning a version even though the package has numerous known advisories, including authentication and command-injection related issues. Because this skill explicitly sets up an MCP broker for direct agent-to-agent messaging, any vulnerable fastmcp release could directly affect message routing, auth boundaries, or code execution paths.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Using uvicorn>=0.30.0 permits installation of any later version, preventing reproducible deployments and making it harder to verify whether deployed instances include vulnerable releases or breaking changes. Although this is a common packaging mistake rather than an exploit by itself, it weakens supply-chain control for a network-facing server component.

Content

Scanner excerpt · scripts/server/requirements.txt (reported line 2)May include surrounding context.

text
fastmcp>=2.0.0
uvicorn>=0.30.0
aiosqlite>=0.20.0

Unverifiable Dependency: uvicorn has 4 known advisory(ies) (CVE-2020-7694 (Log injection in uvicorn); CVE-2020-7695 (HTTP response splitting in uvicorn); CVE-2020-7694 (This affects all versions of package uvicorn. The request logger provided by the) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Uvicorn has known advisories, and the lack of version pinning makes it impossible to determine from this manifest whether deployments will use a fixed, patched release. Since uvicorn is the network-facing application server, vulnerable versions can expose request handling or logging weaknesses to remote clients.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The aiosqlite dependency is also unpinned, which can lead to non-deterministic installs and unreviewed upgrades over time. While no specific advisory is cited here, unpinned dependencies still increase operational and supply-chain risk by reducing version control.

Content

Scanner excerpt · scripts/server/requirements.txt (reported line 3)May include surrounding context.

text
fastmcp>=2.0.0
uvicorn>=0.30.0
aiosqlite>=0.20.0

Static analysis

No suspicious patterns detected.