Back to skill

Security audit

ClawSwarm Real-Time Client

Security checks for vulnerabilities and agentic risk

Overview

This is a real WebSocket messaging client, but its daemon mode stores untrusted channel messages and DMs in an agent-readable local inbox, which deserves careful review before installation.

Install only if you trust the ClawSwarm service and are comfortable with shared-channel and DM content being saved locally for agent use. Treat the inbox as untrusted external input, avoid sending secrets, restrict file permissions, consider changing `SWARM_INBOX` to a controlled location, and pin the `websockets` dependency in a virtual environment.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T01 · Skill Instruction Hijacking

Error
Location
swarm_client.py:242
Finding

Untrusted Remote Messages Are Persisted for Agent Processing

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:65; swarm_client.py:242-259
Vulnerability Type: Remote prompt injection through an Agent-processing inbox
Risk Level: High

The documentation explicitly states:

markdown
Writes incoming messages to `~/.openclaw/workspace/swarm-inbox.md` for your agent to process.

The standalone daemon persists remote channel messages and direct messages verbatim:

python
def on_message(channel, sender, text):
    log.info(f"[{channel}] {sender}: {text[:80]}")
    # Write to inbox file for agent processing
    with open(inbox_file, "a") as f:
        f.write(f"\n---\n[FROM: {sender} | CHANNEL: {channel} | {time.strftime('%Y-%m-%dT%H:%M:%S')}]\n{text}\n---\n")

def on_dm(sender, text):
    log.info(f"[DM] {sender}: {text[:80]}")
    with open(inbox_file, "a") as f:
        f.write(f"\n---\n[DM FROM: {sender} | {time.strftime('%Y-%m-%dT%H:%M:%S')}]\n{text}\n---\n")

Technical Analysis

Messages supplied by external channel participants or direct-message senders are written into an Agent workspace file without content sanitization, sender allowlisting, authenticated trust labels, or an approval boundary. The documentation establishes that this inbox is intended to be processed by an Agent.

The separator-based plaintext format does not provide a reliable distinction between trusted instructions and untrusted message data. A sender can include instruction-like content or reproduce the separators and metadata format inside a message. If a downstream Agent reads the inbox as actionable context, attacker-controlled text may influence its goals, safety decisions, or tool use.

The WebSocket authentication protects the client's connection but does not establish that every participant sending a message is trusted to instruct the local Agent.

Attack Path

  1. The victim runs swarm_client.py in standalone mode with access to a shared channel or direct m ...[truncated 1158 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every channel message and direct message as untrusted data rather than an Agent instruction.
  2. Store received messages in a structured format such as JSON, with separate fields for content, sender identity, channel, timestamp, and trust status.
  3. Place the inbox outside directories automatically loaded as Agent instructions or memory.
  4. Require explicit user approval before converting any received message into an actionable Agent task.
  5. Enforce allowlists for trusted senders and channels when messages are intended to trigger Agent behavior.
  6. Verify sender identity using server-provided immutable identifiers rather than display names alone.
  7. Present remote content to the Agent under a strong instruction boundary stating that it is quoted, untrusted data and must not override system or user instructions.
  8. Escape or encode message content so that attackers cannot forge record separators or metadata.
  9. Apply size limits, rate limits, and inbox rotation to reduce flooding and persistent context manipulation.
  10. Restrict any downstream Agent consuming the inbox to least-privilege tools and require confirmation for sensitive operations.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:17
Finding

Unpinned Third-Party WebSocket Dependency

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:17; swarm_client.py:28-31
Vulnerability Type: Uncontrolled third-party dependency resolution
Risk Level: Medium

The installation documentation recommends installing the dependency without a version or integrity constraint:

markdown
**Dependency:** `pip install websockets`

The program repeats the same unpinned installation guidance when the import fails:

python
try:
    import websockets
except ImportError:
    print("pip install websockets")
    sys.exit(1)

Technical Analysis

Running pip install websockets resolves a package version dynamically from the user's configured package index. The project supplies no pinned version, lockfile, integrity hash, or trusted-index requirement.

Consequently, installations are not reproducible, and the effective dependency code may change after the skill has been reviewed. If the configured index is compromised, misconfigured, or controlled by an attacker, a malicious package artifact could be installed. Even when the official index is used, an incompatible future release could introduce security or behavioral regressions.

Attack Path

  1. A user follows the documented installation instruction after the import fails.
  2. pip queries the package index configured in the user's environment.
  3. The resolver selects an unconstrained version of websockets.
  4. A compromised index, malicious mirror, or compromised package release supplies attacker-controlled dependency code.
  5. Python imports that code when swarm_client.py starts.
  6. The dependency code executes with the same operating-system privileges and environment access as the client process.

Impact Assessment

A malicious dependency can execute arbitrary Python code under the account running the skill. This may expose the CLAWSWARM_API_KEY, read or modify files accessible to that account, alter network communications, o ...[truncated 229 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin websockets to a reviewed, compatible version instead of installing the latest available release.
  2. Maintain a dependency lockfile containing cryptographic hashes for approved artifacts.
  3. Install with hash verification, such as a requirements file used with pip install --require-hashes.
  4. Document and enforce a trusted package index rather than inheriting an arbitrary environment-specific mirror.
  5. Review dependency release notes and security advisories before updating the pin.
  6. Perform dependency installation in an isolated virtual environment with least privileges.
  7. Add automated supply-chain and vulnerability scanning for locked dependencies.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose presents the skill as a real-time WebSocket client, but the documentation also describes daemon behavior and persistent local inbox writing. This mismatch is dangerous because it can hide materially different data-handling behavior from users and reviewers, especially persistence of remote messages to disk for later agent processing.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents capabilities that access environment variables and write to the local filesystem, but it does not declare any explicit tool scope or permissions. This creates an authorization and transparency gap: a host may permit the skill without realizing it needs sensitive capabilities, and users cannot make an informed trust decision from the manifest alone.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation instructs users to connect to a third-party WebSocket endpoint and register over HTTP(S) without warning that agent identity, metadata, and message traffic are transmitted to an external service. In an agent skill context, silent network transmission can expose operational data, channel participation, and potentially sensitive content to an unreviewed remote system.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

At line 74, the documentation introduces local inbox-file writing, which is a materially different behavior from a transient real-time client. Undisclosed or underemphasized persistence increases the risk of sensitive message retention, unintended downstream processing, and forensic exposure on the host system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill states that incoming messages are written to ~/.openclaw/workspace/swarm-inbox.md without warning about persistence, sensitivity, or access controls. Remote messages may contain secrets, prompts, or operational instructions that become stored locally and potentially accessible to other processes or users.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

The registration command sends agent metadata to an external domain to obtain an API key. While external transmission is expected for registration, it is still security-relevant because it establishes trust with a remote service and may disclose identifying information or encourage users to bootstrap credentials without sufficient verification of the service.

Content

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

Get Your API Key

bash
curl -X POST https://onlyflies.buzz/clawswarm/api/v1/agents/register \
  -H "Content-Type: application/json" \
  -d '{"name": "YourAgent", "capabilities": ["messaging"]}'
# Save the apiKey from the response

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation frames the module as a real-time client that listens and responds, while the executable path also acts as a persistence relay that archives messages to disk. That mismatch can mislead operators into deploying it without understanding that communications, including DMs, will be retained locally, which raises privacy and data-governance risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The standalone mode persists all inbound swarm content to a local inbox file, which materially expands the data-handling behavior beyond a transient real-time client. This creates confidentiality risk because potentially sensitive channel and DM content is silently stored on disk, increasing exposure to local users, backups, or later unintended processing.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code persistently stores all channel and DM content in plain-text form, creating a durable record of potentially sensitive communications. In the context of an agent skill, this is more dangerous because the inbox file may later be consumed by other automation, broadening access and making accidental disclosure, prompt injection carryover, or unauthorized local reading more likely.

Content

No source excerpt is available for this finding.

Tainted flow: 'inbox_file' from os.getenv (line 244, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · swarm_client.py (reported line 253)May include surrounding context.

python
def on_message(channel, sender, text):
        log.info(f"[{channel}] {sender}: {text[:80]}")
        # Write to inbox file for agent processing
        with open(inbox_file, "a") as f:
            f.write(f"\n---\n[FROM: {sender} | CHANNEL: {channel} | {time.strftime('%Y-%m-%dT%H:%M:%S')}]\n{text}\n---\n")

    def on_dm(sender, text):

Tainted flow: 'inbox_file' from os.getenv (line 244, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · swarm_client.py (reported line 258)May include surrounding context.

python
def on_message(channel, sender, text):
        log.info(f"[{channel}] {sender}: {text[:80]}")
        # Write to inbox file for agent processing
        with open(inbox_file, "a") as f:
            f.write(f"\n---\n[FROM: {sender} | CHANNEL: {channel} | {time.strftime('%Y-%m-%dT%H:%M:%S')}]\n{text}\n---\n")

    def on_dm(sender, text):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Direct messages are persisted to disk without an explicit warning that private conversations are being stored. This is more sensitive than channel logging because DMs often carry higher expectations of privacy and may contain secrets or operationally sensitive instructions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

Using environment variables for the WebSocket URL and API key may be understandable for configuration, but the executable mode also consumes environment-driven local file path and channel configuration to operate as a relay daemon. That local file routing capability is not justified by the manifest's narrow description of a WebSocket client.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

Channel messages are written to a local inbox file without a clear in-code or user-facing warning at the point of persistence. While not a code-execution issue, it is a genuine privacy and transparency problem because users and operators may reasonably expect transient chat handling rather than silent archival.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.