T09 · Insecure Skill Coding Practices
- Location
scripts/mock_a2a_server.py:383- Finding
Caller-Controlled Webhook URL Enables SSRF and Task-Data Exfiltration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This A2A skill is mostly a coherent protocol guide, but its mock server can expose task data and outbound callbacks more broadly than a local testing tool should.
Review before installing if you plan to run the mock server or send real tasks. Treat remote A2A agents and webhook URLs as external systems, avoid secrets or confidential data unless intended, and run the mock server only in a trusted local environment or after changing it to bind to 127.0.0.1 with authentication and callback restrictions.
scripts/mock_a2a_server.py:383Caller-Controlled Webhook URL Enables SSRF and Task-Data Exfiltration
scripts/mock_a2a_server.py:476Local Mock Server Binds to All Interfaces and Exposes Tasks Without Authentication
scripts/mock_a2a_server.py:277Unbounded HTTP Request Body Allows Memory-Exhaustion Denial of Service
The declared description presents a broad A2A protocol integration skill, but the provided code chunk merely echoes setup and usage information for a local AgentCard validation script. This is a materially different and much narrower behavior than the declared purpose. While the setup script may support a larger A2A-related project, this chunk alone does not perform the advertised protocol capabilities.
The declared description promises a comprehensive A2A interoperability skill, including communication between agents and AgentCard publishing/discovery workflows. The supplied code does not implement any network protocol, client/server behavior, discovery, publishing, delegation, or framework integration. Its actual purpose is much narrower: validating the structure of a local AgentCard JSON file. While AgentCard validation is tangentially related to A2A, it is not an implementation of the broad capabilities described, so the description materially overstates what the code chunk does.
There is a strong description-behavior mismatch. The declared purpose describes a functional A2A protocol skill enabling inter-agent networking features. The actual code chunk contains only repository validation tests for markdown metadata and hygiene. While such tests could support packaging of a skill, they do not implement or expose any of the claimed A2A capabilities. The primary purpose of the code is quality assurance/linting of skill contents, which is materially different from the declared operational networking functionality.
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.
git clone https://github.com//a2a-protocol.git cd a2a-protocol
3. **Create a feature branch**:
```bash
git checkout -b feat/your-feature-name
The README explicitly encourages sending tasks, streaming updates, and subscribing to remote agents, but it does not warn users that task contents, artifacts, and metadata may be transmitted to third-party systems. In a skill focused on cross-agent communication, this omission can lead users to disclose sensitive business data, credentials, or regulated information to external endpoints without informed consent or verification.
The skill instructs the agent to read local files, make network requests, and run shell commands, but it does not declare any explicit tool scope or permission boundaries. That increases the chance of unintended capability exposure, especially because this skill can contact remote agents and launch a local mock server.
The send-task mode directs the agent to transmit task content to a remote A2A agent but does not instruct it to warn the user that their data will be disclosed externally. Because task payloads may include messages, context, files, or structured data, this can result in unintentional data exfiltration to remote services.
The webhook subscription flow sends task results to an external callback URL, but the skill does not require an explicit user-facing warning that data will leave the local environment. In practice, this can expose prompts, artifacts, identifiers, or sensitive outputs to third-party infrastructure if the user or agent configures an external endpoint.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
1. POST to https://target-agent/a2a/tasks/send with hardcoded payload
2. Assume success without checking status.state
3. Return raw task object instead of artifacts[].parts
The webhook subscription example explicitly includes API key credentials and a secret payload for push delivery, but the reference does not warn implementers about the sensitivity of these fields, endpoint trust, or the risk of forwarding secrets to third-party push providers. In an A2A interoperability reference, omission of these cautions can lead developers to embed long-lived credentials in outbound configs or send them to untrusted endpoints, increasing the chance of credential leakage, SSRF-style abuse, or unauthorized callback delivery.
The file presents the service as a local mock server for testing, but the implementation listens on 0.0.0.0, exposing it on all network interfaces. In combination with task APIs and outbound callback behavior, this increases the chance that a developer unintentionally publishes an insecure test service to a LAN or broader network.
The server exposes task listing and retrieval endpoints without any authentication or authorization, while also advertising extended-card and push-notification capabilities. Because the service binds publicly and stores task contents in memory, any reachable caller can enumerate or fetch task data, which can leak prompts, outputs, session identifiers, or other sensitive testing data.
The tasks/subscribe handler performs an outbound POST to a client-supplied pushProviderUrl with no validation, allowlisting, or warning. This enables server-side request forgery behavior: a remote caller can induce the server to send HTTP requests to arbitrary destinations reachable from the host, including internal services, and transmit task data to them.
The README explicitly promotes sending tasks to remote agents and using streaming/push workflows, but it does not warn users that prompts, task data, metadata, or callbacks may leave the local environment and be transmitted to third-party systems. In an agent-integration skill, that omission can cause unintentional data disclosure or unsafe deployment assumptions, especially when users treat documentation commands as low-risk setup steps.
The usage examples show commands for remote task submission, live streaming, and subscription without any adjacent notice that these actions can trigger outbound network requests and ongoing data exchange with external agents. Because users often copy commands directly from quick-start sections, the missing warning increases the chance of accidental exposure of prompts, files, or internal service endpoints.
The quickstart shows an Authorization Bearer token directly in an HTTP example without clearly labeling it as a dummy placeholder or warning readers not to reuse real credentials in documentation, logs, or screenshots. In an integration-focused skill like A2A, users are likely to copy examples verbatim, which can normalize unsafe token handling and lead to accidental credential exposure if real tokens are substituted into code samples, terminals, or tickets.