Back to skill

Security audit

communication-mqtt

Security checks for vulnerabilities and agentic risk

Overview

This is a small local MQTT messaging skill with clear purpose, but users should treat published agent details as visible to anyone who can access the broker.

Install only in a controlled local environment with a trusted MQTT broker. Prefer a virtual environment and pinned dependencies, extract only the needed agent_id instead of printing the full OpenClaw config, avoid publishing sensitive roles or activities, and configure broker authentication, ACLs, TLS when crossing trust boundaries, and clear rules for retained messages.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (4)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:27
Finding

OpenClaw Configuration Is Unnecessarily Exposed to Terminal Output

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:22
Finding

Third-Party Python Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/publish.py:8
Finding

MQTT Agent Metadata Is Exchanged Without Client Authentication or Transport Confidentiality

Content
View full analysis
int: return int(time.time()) def publish_message(topic: str, payload: dict): publish.single( topic=topic, payload=json.dumps(payload), hostname=BROKER, port=PORT, qos=QOS, retain=RETAIN, ) typer.echo(f"Published to {topic}") typer.echo(json.dumps(payload, indent=2)) ``` From `scripts/subscribe.py`: ```python # 🔒 고정 MQTT 설정 BROKER = "localhost" PORT = 1883 KEEPALIVE = 30 QOS = 1 ``` ```python client = mqtt.Client(client_id=f"sub-{kind}", clean_session=True) client.on_connect = on_connect client.on_message = on_message client.connect(BROKER, PORT, keepalive=KEEPALIVE) ``` ### Technical Analysis Both clients connect to the conventional plaintext MQTT port and configure neither TLS nor MQTT credentials. The publisher also sets `retain=True`, causing the broker to preserve the latest agent introduction or status message for future subscribers. The broker is fixed to `localhost`, which limits direct exposure compared with a remote broker. However, the scripts do not require broker authentication, topic authorization, or publisher identity verification. If the local broker permits anonymous access, any other local process able to connect to it may subscribe to agent topics, publish forged messages, or replace retained records. Transport confidentiality is especially relevant if broker configuration, container networking, forwarding, or deployment changes make the endpoint reachable beyond a strictly trusted host. The scripts themselves provide no defense against such changes. ### Attack Path 1. ...[truncated 1142 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/publish.py:36
Finding

Unvalidated Agent Identifiers Can Alter MQTT Topic Routing Semantics

Content
View full analysis
str: return f"agents/{agent_id}/{kind}" if agent_id else f"agents/+/{kind}" ``` ```python @app.command() def intro( agent_id: str = typer.Option( None, "--agent-id", "-i", help="If provided: agents//intro. Otherwise: agents/+/intro", ), wait: float = typer.Option( 0.0, "--wait", "-w", help="Seconds to keep listening after subscribe (default: 0, one-shot).", ), ): """ Subscribe and print intro messages, then exit. """ _run_subscribe("intro", agent_id, wait) @app.command ...[truncated 2514 chars]
Remediation
View remediation
str: if not _AGENT_ID.fullmatch(value): raise typer.BadParameter( "agent_id must contain only letters, digits, underscores, or hyphens" ) return value ``` - Explicitly reject `/`, `+`, `#`, null characters, control characters, empty values, and excessive lengths. - Keep the intentional all-agent subscription as a separate explicit command or option rather than deriving wildcard behavior from identifier input. - Apply broker ACLs as defense in depth so a malformed filter cannot expand beyond the client's authorized namespace. - Add tests covering wildcard characters, nested topic separators, Unicode control characters, empty identifiers, and maximum lengths. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

설명은 에이전트의 Intro/Status 메시지를 '발행하고 구독'하는 기능이라고 했지만, 제공된 코드는 paho.mqtt.publish를 사용해 두 종류의 메시지를 MQTT로 발행하는 CLI만 구현한다. 구독 로직이나 MQTT 수신 처리는 전혀 없다. 또한 intro payload에 MQTT와 별개로 openclaw 명령을 통한 직접 통신 방법을 안내하는 채널 문자열을 삽입하는 동작이 설명에 명시되어 있지 않다. 주요 목적은 intro/status 발행과 대체로 관련 있지만, 핵심 기능 중 하나로 서술된 구독이 빠져 있으므로 설명과 행동은 정확히 일치하지 않는다.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

설명은 Intro/Status 메시지를 '발행하고 구독'하는 기능 전반을 제공한다고 주장하지만, 제공된 코드 청크는 subscribe.py로서 MQTT 브로커(localhost:1883)에 접속하여 intro/status 토픽을 구독하고 수신 메시지를 출력하는 기능만 구현한다. publish 호출이나 메시지 송신 로직은 전혀 없다. 따라서 설명이 실제 동작보다 넓고, 특히 핵심 capability인 발행 기능이 부재하므로 설명과 코드 사이에 중요한 불일치가 있다. 다만 MQTT를 사용해 Intro/Status 메시지를 다룬다는 큰 범주는 일부 부합한다.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly instructs users to publish agent identifiers, roles, and live activity updates over MQTT, but provides no warning about metadata exposure, broker access control, retention, or plaintext transport. In a multi-agent environment, this can leak sensitive operational details to anyone with broker access and enable tracking, profiling, or targeting of agents.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/subscribe.py (reported line 57)May include surrounding context.

python
# 1) connect + subscribe 완료될 때까지 잠깐 돌림 (최대 2초)
    deadline_connect = time.time() + 2.0
    while not connected.is_set() and time.time() < deadline_connect:
        client.loop(timeout=0.1)

    if not connected.is_set():
        print("Failed to connect/subscribe within 2 seconds.")

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/subscribe.py (reported line 68)May include surrounding context.

python
# 1) connect + subscribe 완료될 때까지 잠깐 돌림 (최대 2초)
    deadline_connect = time.time() + 2.0
    while not connected.is_set() and time.time() < deadline_connect:
        client.loop(timeout=0.1)

    if not connected.is_set():
        print("Failed to connect/subscribe within 2 seconds.")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The comment # 🔒 고정 MQTT 설정 is written only in Korean, which introduces a language-specific constraint in the skill file without offering any user choice or documenting a justified locale requirement. This can violate organizational language/locale policy when skills are expected to be accessible or neutral by default.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.