Back to skill

Security audit

A2a Msg

Security checks for vulnerabilities and agentic risk

Overview

This Redis messaging skill is not clearly malicious, but it needs Review because its auto mode lets Redis messages trigger local actions and automatic replies without strong sender authentication or secure transport.

Install only if you trust and secure the Redis server, understand that auto mode can process queued messages as commands, and are willing to accept automatic replies and local skill-name disclosure. Avoid scheduling auto mode, avoid exposing Redis directly, prefer TLS or a private tunnel with ACLs, and do not use it with sensitive messages until sender authentication and per-command authorization are added.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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)

T06 · System Persistence

Warning
Location
SKILL.md:132
Finding
Optional Scheduled Task Creates Persistent Unattended Message Processing<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:132-138` **Vulnerability Type**: Persistence through Windows Task Scheduler **Risk Level**: Medium ### Vulnerable Code ```markdown ## Scheduled Task You can configure automatic message checking: ```bash # Run automatically every day at 23:00 schtasks /create /tn "A2A_Poll" /tr "python scripts/a2a.py auto" /sc daily /st 23:00 ``` ``` ### Technical Analysis The documentation instructs the user to register a Windows scheduled task that launches the Skill's automatic message-processing mode every day. Although this step is disclosed and requires user action, it creates cross-session persistence and is not required for the basic send, poll, peek, or queue-status functionality. The scheduled command uses an unqualified `python` executable and a relative path, `scripts/a2a.py`. Its behavior therefore depends on the scheduler's working directory and executable search path. If an attacker can place or modify a file at the resolved script location, or influence which Python executable is selected, the task may repeatedly execute unintended code. The more immediate risk is that `auto` processes messages from Redis without message-level authentication. Scheduling it unattended converts that behavior into a recurring remote command-processing channel. ### Attack Path 1. The user runs the documented `schtasks /create` command. 2. The task persists across sessions and runs daily without further confirmation. 3. An attacker with access to the configured Redis instance inserts a forged message into the agent's queue. 4. At the scheduled time, `scripts/a2a.py auto` consumes and processes the message. 5. Supported local operations are executed and the result may be returned to an attacker-selected sender queue. 6. If the relative script path or PATH-resolved Python executable is writable or replaceable, modified code can also be executed each time the task runs. ### Impact Assessment The task provides re ...[truncated 400 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove scheduled-task registration from the normal setup flow, or require explicit, informed opt-in. - Do not schedule `auto` mode until message authentication and authorization controls are implemented. - Use fully qualified, quoted paths for both the trusted Python interpreter and the script. - Configure an explicit working directory rather than relying on scheduler defaults. - Run the task under a dedicated, least-privileged account. - Restrict write permissions on the interpreter, project directory, and script. - Document how to inspect and remove the task, for example with `schtasks /delete`. - Prefer a foreground polling process that requires user confirmation for sensitive operations. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/a2a.py:246
Finding
Redis Messages Are Treated as Authorized Commands Without Sender Authentication<![CDATA[ ## Vulnerability Details **File Location**: `scripts/a2a.py:66-78, 246-264` **Vulnerability Type**: Missing authentication and authorization for remotely supplied commands **Risk Level**: High ### Vulnerable Code ```python def receive_messages() -> list: """Receive messages from the message queue.""" r = get_redis() queue_key = f"msgs_{CONFIG['my_id']}" messages = [] while True: msg = r.rpop(queue_key) if not msg: break try: data = json.loads(msg) messages.append(data) except: pass return messages ``` ```python def auto_process() -> str: """Automatically process queued messages.""" messages = receive_messages() if not messages: return "No new messages need processing" results = [] for msg in messages: sender = msg.get("from", "unknown") content = msg.get("content", "") print(f"Processing message from {sender}: {content}") result = process_message_with_ai(content) results.append(f"From {sender}: {content}\n→ {result}") if sender != CONFIG["my_id"]: send_message(sender, result) return "\n\n".join(results) if results else "Processing complete" ``` ### Technical Analysis A message consists only of attacker-controlled JSON fields such as `from` and `content`. The implementation does not verify a digital signature or message authentication code, enforce an approved-sender list, validate freshness, prevent replay, or authorize individual commands. Possession of Redis write access is therefore treated as sufficient authority to issue commands. The `from` value is also trusted when selecting the response queue, allowing a sender to impersonate another agent or direct output to an arbitrary queue name. The commands currently implemented are constrained and do not directly execute arbitrary shell input. Nevertheless, they can enumerate local skill names ...[truncated 1772 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Authenticate every message using a per-peer HMAC or asymmetric digital signature. - Sign all security-relevant fields, including sender, recipient, content, timestamp, nonce, and protocol version. - Maintain an explicit allowlist of authorized peer identities. - Authorize commands per peer rather than treating every authenticated peer as fully trusted. - Reject stale messages and maintain a replay cache for previously accepted nonces. - Validate JSON against a strict schema, including type and length limits. - Do not use an untrusted `from` field directly as a destination queue without validation. - Require user confirmation for operations that access local resources or relay messages. - Use Redis ACLs that restrict each agent to only the queue keys and commands it requires. - Add rate limiting and retain security logs for rejected and accepted command requests. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/a2a.py:36
Finding
Redis Credentials and Messages May Be Transmitted Without TLS<![CDATA[ ## Vulnerability Details **File Location**: `scripts/a2a.py:36-43` **Vulnerability Type**: Plaintext transmission of credentials and command messages **Risk Level**: High ### Vulnerable Code ```python def get_redis(): """Create a Redis connection.""" return redis.Redis( host=CONFIG["host"], port=CONFIG["port"], password=CONFIG["password"], decode_responses=True ) ``` The documented Redis deployment also publishes the standard plaintext Redis port: ```yaml services: redis: image: redis:alpine container_name: redis-a2a ports: - "6379:6379" command: redis-server --requirepass your-password restart: unless-stopped ``` ### Technical Analysis The Redis client is created without `ssl=True`, a `rediss://` URL, certificate verification settings, or another protected transport. The Skill explicitly supports connecting to a separately hosted Redis server, so the password and message contents may traverse an untrusted network in plaintext. Redis password authentication does not encrypt the connection. A network-positioned attacker may observe the authentication exchange and queue contents. If active interception is possible, the attacker may also tamper with commands or responses. This issue is especially significant because Redis access is the effective authorization boundary for automatic command processing. Capturing the Redis password may therefore permit message forgery in addition to disclosure. ### Attack Path 1. The user configures a remote Redis host and password. 2. The Skill connects to port 6379 without TLS. 3. A network-positioned attacker observes traffic between the agent and Redis. 4. The attacker captures the Redis credential or sensitive queue messages. 5. Using the captured credential, the attacker connects to Redis if network access is available. 6. The attacker writes a forged message to the victim's queue. 7. The victim's `auto` mode accepts and processes the ...[truncated 516 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require TLS for remote Redis connections by using `rediss://` or `ssl=True`. - Enable server-certificate validation and configure a trusted CA; do not disable hostname verification. - Reject non-TLS remote connections by default. - Bind Redis to a private interface and place it behind a VPN or mutually authenticated tunnel. - Do not expose port 6379 directly to the public Internet. - Use Redis ACL users with unique credentials per agent and access limited to required commands and key patterns. - Rotate existing passwords if they may previously have crossed an untrusted network. - Add application-level message signatures so transport compromise alone does not authorize commands. - Update deployment documentation to provide a secure TLS-enabled Redis configuration. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/a2a.py:174
Finding
Hard-Coded Personal Skills Path Can Disclose Local Capability and Filesystem Information<![CDATA[ ## Vulnerability Details **File Location**: `scripts/a2a.py:34, 174-181` **Vulnerability Type**: Hard-coded local path and unauthorized information disclosure **Risk Level**: Low ### Vulnerable Code ```python # Skills directory SKILLS_DIR = r"C:\Users\zhengzhicheng\.openclaw\workspace\skills" ``` ```python def execute_list_skills() -> str: """List installed skills.""" try: skills = os.listdir(SKILLS_DIR) skill_list = "\n".join([f"- {s}" for s in skills]) return f"My current skill list:\n{skill_list}" except Exception as e: return f"Failed to retrieve skill list: {e}" ``` ### Technical Analysis The source contains a developer-specific absolute path that reveals a local username and assumes a fixed Windows workspace layout. This creates both portability and information-disclosure concerns. When automatic processing receives a matching `show skills` command, the function returns directory entry names to the remote sender. If directory enumeration fails, the raw exception text is returned instead. Such exceptions may include the absolute local path and operating-system details. Because message senders are not authenticated at the application layer, any party with Redis write access can request this information. ### Attack Path 1. An attacker gains the ability to write to the configured Redis instance. 2. The attacker pushes a message such as `show skills` to the victim agent's queue. 3. The victim executes `auto_process()`. 4. Command matching selects `execute_list_skills()`. 5. The code enumerates the hard-coded local directory. 6. Directory names are returned to the attacker, or a raw exception reveals the local path and related environment details. ### Impact Assessment The issue can disclose: - A local Windows username embedded in the source. - Installed skill or capability names. - Workspace layout and operating-system path conventions. - Exception details useful for reconnaissance. The functi ...[truncated 211 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the developer-specific absolute path from the source. - Resolve the workspace through a trusted runtime API or a validated configuration value. - Restrict the configured directory to an approved skills root and canonicalize it before use. - Require authenticated and authorized peers before exposing local capability information. - Return only an allowlisted set of public skill names rather than raw directory entries. - Replace raw exception messages with generic remote-facing errors. - Record detailed exceptions only in protected local logs. - Avoid committing personal usernames or environment-specific paths to distributable Skill packages. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared purpose is message passing over Redis, but the documented behavior includes automatically interpreting messages, listing local skills, executing local commands, and sending replies based on remote input. That mismatch hides a remote-action surface behind a benign description, which can lead users to enable a skill that effectively acts on untrusted messages.

Vague Triggers

High
Confidence
96% confidence
Finding
The auto-processing trigger uses very vague commands like '自动处理' and 'auto' for a mode that interprets incoming messages and executes actions. Because the trigger lacks strong invocation constraints, the skill could be activated accidentally and then process attacker-controlled Redis messages as commands.

Missing User Warnings

High
Confidence
97% confidence
Finding
The auto mode description says AI will understand messages, execute corresponding operations, and automatically reply, but it does not clearly warn that untrusted remote messages can drive local actions. In this context, Redis acts as an external command channel, so lack of warning materially increases the chance that users enable behavior equivalent to remote instruction execution.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
The skill is presented as Redis-based messaging, but it also auto-interprets inbound messages and performs local actions such as listing local skills, checking queues, and sending further messages. This creates a remote command surface over Redis, so anyone able to enqueue messages for this agent can trigger unintended local behaviors without user approval.

Credential Access

High
Category
Privilege Escalation
Content
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# 配置 - 从环境变量读取
# 设置方式(添加到 ~/.openclaw/.env 或系统环境变量):
#   A2A_REDIS_HOST=Redis服务器地址
#   A2A_REDIS_PORT=6379
#   A2A_REDIS_PASSWORD=密码
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

High
Confidence
99% confidence
Finding
auto_process consumes inbound Redis messages and immediately performs matched actions without confirmation, trust validation, or sender authentication. In this context, Redis becomes a remote trigger channel for local operations and automatic replies, enabling unauthorized actioning, information disclosure, and possible message-loop abuse.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill declares no explicit tool scope or permission boundaries despite requiring environment variables and documenting network, file access, and shell-based execution paths. This is dangerous because users and orchestrators cannot accurately assess or constrain what the skill may access, increasing the chance of unintended capability exposure.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The receive-message activation examples are broad phrases such as '查看消息' and 'poll', which may be triggered in normal conversation without clear user intent to invoke the skill. Overbroad triggers can cause unintended polling of external message queues and expose the agent to untrusted remote content unexpectedly.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The skill’s natural-language description and command interface are primarily Chinese-only, and the embedded help text assumes Chinese-language interaction without offering a language choice. This creates a locale/language policy concern because the file imposes a specific language experience without explicit user opt-in or justification.

Missing User Warnings

Medium
Confidence
81% confidence
Finding
The code pushes message content to Redis, which transmits user-provided data over the network or IPC boundary, but there is no explicit warning about this data transfer beyond an implementation docstring. For users invoking the send flow, the script does not disclose that message contents are being stored in and transmitted via Redis.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The message handler exposes local filesystem inventory by listing the skills directory in response to inbound text. This leaks environment details to remote peers and helps an attacker profile available capabilities for follow-on abuse.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The weather handler invokes subprocess.run, and this path is reachable from incoming message interpretation. Even though the subprocess currently only prints guidance text, process creation is a powerful local capability unrelated to the stated purpose of Redis-based instance communication.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""执行查天气"""
    try:
        # 调用天气skill
        result = subprocess.run(
            ["python", "-c", "import urllib.request; print('请使用天气skill查询')"],
            capture_output=True, text=True, timeout=5
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
Most of the skill description and usage guidance are presented only in Chinese, with only partial English trigger examples. There is no explicit statement that users may choose their preferred language, so this may conflict with a policy requiring language or locale choice unless the locale restriction is documented and justified.

Intent-Code Divergence

Low
Confidence
84% confidence
Finding
The module docstring claims the skill 'supports AI understanding and automatic command execution,' suggesting broader semantic interpretation. In practice, process_message_with_ai only performs deterministic regex matching against a small set of hardcoded patterns and dispatches fixed functions, which does not match the documented behavior. This is an intent-level documentation overstatement rather than a mere omitted detail.

Static analysis

No suspicious patterns detected.