Back to skill

Security audit

A2a

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent agent-to-agent communication library, but it exposes networked agent calls without clear authentication, transport security, or user-facing data-sharing warnings.

Review this carefully before installing or using it for real agents. It may be acceptable for local experiments or trusted test networks, but do not send secrets, private user data, credentials, or consequential tasks through it unless you add endpoint allowlisting, authenticated peers, encrypted transport, and explicit user approval for outbound delegation.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:67
Finding

Unpinned Package Execution in Installation Instructions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:67
Vulnerability Type: Unpinned third-party package execution
Risk Level: Medium

Vulnerable Code Snippet:

bash
npx clawhub install a2a-waai

Technical Analysis

The documented installation command invokes a third-party package through npx without specifying an audited version or integrity value. Consequently, the package resolved when the command is executed may differ from the package that existed when this skill was reviewed.

This creates a supply-chain trust risk. If the relevant package, publisher account, package registry, or dependency chain is compromised, an attacker could distribute altered installation behavior under the expected package name. The command would then retrieve and execute that changed package in the user's environment.

Attack Path

  1. An attacker compromises the package, its publisher account, or an associated supply-chain component.
  2. The attacker publishes a modified release containing malicious installation behavior.
  3. A user follows the documented command without a pinned version or integrity check.
  4. npx resolves the current package release from the configured registry.
  5. The altered package executes with the privileges of the user running the installation.

Impact Assessment

Successful exploitation could allow arbitrary code execution with the installing user's privileges. Depending on those privileges, the attacker may be able to access user files, credentials, agent configuration, and network resources or modify other locally accessible software. The exact impact depends on the behavior of the externally supplied package and the privileges under which installation occurs.

Remediation
View remediation

Remediation Suggestions

  • Pin the package to a specific, audited version rather than resolving the latest available release.
  • Document the trusted package registry and avoid implicit resolution from untrusted or user-controlled registries.
  • Verify the downloaded artifact using a cryptographic integrity hash or signed provenance information.
  • Review the package and its transitive dependencies before recommending installation.
  • Use a lockfile or equivalent reproducible dependency mechanism where supported.
  • Run installation with the minimum required privileges and avoid privileged or administrative execution.

T09 · Insecure Skill Coding Practices

Error
Location
a2a.py:38
Finding

Unauthenticated and Unauthorized Action Dispatch

Content
View full analysis

Vulnerability Details

File Location: a2a.py:38-46
Vulnerability Type: Missing authentication and action-level authorization
Risk Level: High

Vulnerable Code Snippet:

python
class Server:
    """优雅服务端 - 装饰器注册"""
    def __init__(s, id, host="0.0.0.0", port=8766):
        s.id, s.host, s.port, s.h={}, host, port, {}
    def action(s, n): return lambda f: s.h.__setitem__(n,f) or f
    async def handle(s, m:dict)->dict:
        try:
            msg=Msg(**{k:v for k,v in m.items() if k in Msg.__annotations__})
            h=s.h.get(msg.action)
            r=await h(msg.params) if h else None
            return Resp(id=m.get("id",""), status="ok", result=r).to_dict()
        except Exception as e:
            return Resp(id=m.get("id",""), status="error", error=str(e)).to_dict()

Technical Analysis

Server.handle constructs a message from caller-controlled fields and dispatches the requested action directly from the registered handler table. It does not authenticate the calling agent, validate message integrity, or verify that the caller is authorized to invoke the selected action.

Although messages contain a src field, this value is caller-supplied and is not used for identity verification or authorization. Any transport that exposes handle to untrusted clients would therefore make all registered actions available to those clients. The default host value of 0.0.0.0 also indicates an intended externally reachable configuration, although this file does not itself implement the listening transport.

Attack Path

  1. An application embeds Server.handle in a WebSocket or another network-facing transport.
  2. The attacker obtains network access to that transport.
  3. The attacker identifies or guesses a registered action name.
  4. The attacker submits a message containing the selected action and attacker-controlled params; any claimed src value can be supplied.
  5. ` ...[truncated 762 chars]
Remediation
View remediation

Remediation Suggestions

  • Authenticate every peer before accepting action requests, using mutually authenticated TLS, signed tokens, or another protocol appropriate to the deployment.
  • Do not trust the message's src field as proof of identity; bind identity to an authenticated connection or cryptographically verified credential.
  • Define an explicit per-identity allowlist of actions and enforce authorization before handler lookup and execution.
  • Validate each action's parameters against a strict schema, including types, allowed values, lengths, and nesting limits.
  • Reject unknown actions with an explicit error instead of returning a successful response with an empty result.
  • Add replay protection by signing message identifiers, timestamps, and nonces.
  • Bind to a loopback interface by default unless external exposure is explicitly required.
  • Run the server with minimum privileges and isolate sensitive handlers into separate security domains where practical.
  • Record authenticated identity, requested action, authorization result, and execution outcome in security logs without exposing secrets.

T09 · Insecure Skill Coding Practices

Warning
Location
a2a.py:52
Finding

Plaintext WebSocket Connections Permit Message Interception and Modification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:50; a2a.py:52-66
Vulnerability Type: Unencrypted network transport
Risk Level: Medium

Vulnerable Code Snippets:

python
# Client / 客户端  
c = Client('caller')
r = await c.call('ws://host:8766', 'action', {})
python
class Client:
    """高性能客户端 - 连接池"""
    def __init__(s, aid, pool=10):
        s.aid, s.pool, s.conn=aid, pool, {}
    async def call(s, ep, act, p, to=30)->dict:
        import websockets
        if ep not in s.conn:
            s.conn[ep]=await websockets.connect(ep, max_size=s.pool)
        msg=Msg(id=uuid.uuid4().hex[:8], typ="call", src=s.aid, action=act, params=p).to_dict()
        await s.conn[ep].send(json.dumps(msg))
        return json.loads(await asyncio.wait_for(s.conn[ep].recv(), timeout=to))
    async def cast(s, ep, act, p):
        import websockets
        if ep not in s.conn:
            s.conn[ep]=await websockets.connect(ep, max_size=s.pool)
        msg=Msg(id=uuid.uuid4().hex[:8], typ="cast", src=s.aid, action=act, params=p).to_dict()
        await s.conn[ep].send(json.dumps(msg))

Technical Analysis

The documented example explicitly uses the plaintext ws:// scheme. The client accepts an arbitrary endpoint and passes it directly to websockets.connect without requiring wss:// or establishing an authenticated application-level channel.

When ws:// is used, action names, parameters, claimed source identities, and responses are transmitted without transport encryption or peer authentication. An attacker with a suitable network position can observe these messages or modify them in transit. Because the protocol also lacks message signatures, the receiver has no application-level mechanism to detect tampering.

Attack Path

  1. A user follows the documented example or otherwise supplies a ws:// endpoint.
  2. The client establishes an unencrypted WebSocket connection. 3 ...[truncated 898 chars]
Remediation
View remediation

Remediation Suggestions

  • Require wss:// endpoints and reject plaintext ws:// URLs by default.
  • Configure certificate validation using a trusted certificate authority and verify the expected hostname.
  • For sensitive deployments, use mutual TLS so both client and server identities are authenticated.
  • Add application-level message authentication or digital signatures covering the message identifier, source, destination, action, parameters, and freshness data.
  • Prevent downgrade attacks by never silently falling back from wss:// to ws://.
  • Update all documentation and examples to use authenticated TLS endpoints.
  • Avoid placing secrets in messages unless transport security and peer identity have been verified.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description uses broad activation language such as calling other AI agents, delegating tasks, and cross-platform collaboration without clear limits on when external communication is appropriate. This can cause over-invocation of a networked skill and accidental transmission of sensitive prompts or data to third-party agents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill describes discovery and invocation of other AI agents but does not warn that task content may be sent off-system to external services. For an interconnect skill, that omission is particularly dangerous because the primary function is remote communication, increasing the chance of unintentional data exfiltration, privacy violations, or policy bypass via third-party agents.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The installation command uses npx clawhub without pinning a specific package version, which makes installs non-reproducible and exposes users to supply-chain risk if a newer malicious or compromised release is published. In a skill specifically designed to connect to external agents, this is more concerning because users are already being guided to install and trust network-capable tooling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file's human-readable title, comments, and docstrings are written in Chinese throughout, which imposes a specific language on users and maintainers without any opt-in or justification. Under the policy, locale-specific language should either be optional or clearly documented as required for a region-specific purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill is described as an agent interconnect component for discovering and invoking other agents, which implies preserving agent identity and endpoint configuration correctly. However, Server.__init__ assigns s.id, s.host, s.port, s.h = {}, host, port, {}, discarding the supplied id and setting s.id to an empty dict, so the server does not actually maintain the agent identity its interface suggests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The client opens WebSocket connections to arbitrary endpoints and transmits message data without any transport security, authentication, or trust validation visible in this code. In an agent-interconnect skill, this is more dangerous because it is explicitly designed to discover and invoke other agents, so intercepted or spoofed traffic could expose task data or enable unauthorized cross-agent interaction.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.