Back to skill

Security audit

agnt-data

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a disclosed agntdata social-data API reference, but it also adds broad webhook collection that can persist raw third-party payloads with weak URL-only authentication.

Install only after reviewing whether you are comfortable sending social-data queries and any webhook contents to agntdata. Treat AGNTDATA_API_KEY and webhook receive URLs as secrets, do not use production webhooks unless you can independently verify sender authenticity and sanitize payloads, avoid unnecessary contact-data lookups, and review any recommended npm plugin separately before installing it.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (18)

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The manifest frames this as a unified social data API skill, but the file also introduces generic webhook hosting and arbitrary third-party event ingestion. That scope expansion is security-relevant because it grants the skill a broader data collection and integration surface than users would reasonably expect from the declared purpose.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The hosted webhook receiver accepts events from arbitrary third-party services, which is unrelated to the stated social-data use case and substantially broadens the skill's operational scope. In an agent environment, this can turn a data-fetching skill into a general inbound data sink, increasing the risk of unexpected sensitive data capture and unsafe downstream processing.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The documented `download_media` endpoint accepts an arbitrary `url` parameter, which is a classic indicator of potential server-side request forgery or proxy-abuse risk if the backend fetches attacker-controlled URLs. In an agent context, this can be abused to retrieve internal resources, access restricted hosts, or turn the service into an unauthorized downloader if strict validation is absent.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The documented endpoints to retrieve a YouTube channel's email expose privacy-sensitive contact information that is not clearly necessary for the stated purpose of a unified social data API. In an agent context, this enables automated harvesting of creator contact details at scale, increasing risk of spam, profiling, and misuse.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Channel email lookup is a capability expansion beyond ordinary metadata retrieval and is not justified in the README by a clear, limited business purpose. Because the skill is designed for LLM and automation use, the lack of purpose limitation makes bulk collection and downstream misuse more feasible.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The webhook section encourages users to expose third-party webhook traffic, while only later noting that raw JSON bodies, headers, and source IPs are stored. Without an upfront privacy warning, users may route sensitive vendor events into the service without understanding that personal data, secrets in headers, or regulated content may be retained.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The README explicitly advertises access to Instagram profiles, reels, locations, hashtags, and media download functionality, but provides no guidance on lawful use, privacy constraints, consent, rate limiting, or data retention. In an agent-oriented skill, that omission increases the risk that downstream users automate bulk collection or downloading of personal/social data without adequate safeguards.

Missing User Warnings

Medium
Confidence
74% confidence
Finding
The skill documents extensive profile, company, recommendation, reaction, comment, and hiring data retrieval via a third-party API without any privacy, consent, or data-handling warnings. In an agent setting, this increases the chance that sensitive personal or employment-related data will be collected and transmitted externally without the user understanding the scope, creating privacy and compliance risk.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README instructs users to send an API bearer token and potentially sensitive user/query data to an external third-party service, but it does not warn about privacy, retention, or downstream handling of submitted data. In an agent skill context, this increases the risk that operators unknowingly route user prompts, identifiers, and social graph queries to an external processor without informed consent or data-governance review.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Publishing email-retrieval endpoints without any privacy or compliance warning normalizes use of a sensitive capability and may lead integrators to invoke it without assessing consent, platform rules, or data protection obligations. In an agentic workflow, omission of such warnings materially raises the chance of abusive automation.

External Transmission

Medium
Category
Data Exfiltration
Content
### Concepts

- **Endpoint** — a named receiver in the user's workspace. Created with a friendly `name` (e.g. `stripe-prod`); identified by a UUID `id`.
- **Receive URL** — `https://api.agntdata.dev/webhooks/ingest/<endpointId>`. The endpoint id IS the secret in the URL — treat it like a credential. There is no signature verification; the URL is the auth.
- **Delivery** — one inbound POST, captured with the raw JSON body, the headers the third party sent, and the source IP. Has an `acknowledgedAt` timestamp that starts `null`.
- **Acknowledge** — mark a delivery as processed so it stops appearing in `unacknowledged: true` queries. Does NOT delete the delivery; history is retained.
Confidence
96% confidence
Finding
The webhook design states that the endpoint ID embedded in the URL is the only secret and that there is no signature verification; anyone who learns the URL can submit arbitrary events. In context, this is more dangerous because the service stores raw payloads, headers, and source IPs, enabling spoofed event injection and potential downstream automation on untrusted data.

External Transmission

Medium
Category
Data Exfiltration
Content
### Typical Agent Flow

1. **Create the endpoint** — `POST /v1/webhook-endpoints` with `{ "name": "stripe-prod" }`. Returns `{ id, name, url }`. Show the `url` to the user and tell them to paste it into the third party's webhook configuration.
2. **Wait for events** — the third party POSTs to `https://api.agntdata.dev/webhooks/ingest/<id>`. Each POST is stored as a delivery; nothing is forwarded synchronously.
3. **Poll for new work** — `GET /v1/webhook-endpoints/deliveries?unacknowledged=true&endpointId=<id>` (or omit `endpointId` to query across all endpoints in the workspace).
4. **Process each `rawPayload`** — it's the exact JSON the vendor sent. Parse it the way that vendor documents (e.g. for Stripe, switch on `type` and read `data.object`).
5. **Acknowledge** — call `POST /v1/webhook-endpoints/deliveries/ack` with `{ "ids": [...] }` (or single via `POST /v1/webhook-endpoints/deliveries/{id}/ack`) so the next poll doesn't re-deliver them.
Confidence
96% confidence
Finding
The documented agent flow instructs users to hand a secret-bearing URL to arbitrary third parties and then process exact raw payloads later, but provides no authenticity validation beyond possession of the URL. This creates a spoofable inbound event channel that can feed untrusted data into agents and business workflows.

External Transmission

Medium
Category
Data Exfiltration
Content
| Method | Path | Summary |
|--------|------|---------|
| `POST` | `/v1/webhook-endpoints` | Create a new agntdata webhook endpoint. Returns { id, name, url } where `url` is a public HTTPS endpoint of the form https://api.agntdata.dev/webhooks/ingest/<id>. Give that URL to a third party (Stripe, Calendly, GitHub, your own service, etc.) so they can POST events to it. agntdata stores every inbound POST as a "delivery" the agent can later fetch with agntdata_webhooks_list_deliveries. The `name` is a workspace-unique label (3-50 chars, lowercase + hyphens) that you can show to the user; it is NOT part of the receive URL. Use this when the user asks to "set up a webhook", "give me a URL to receive events", or "let me ingest events from <vendor>". |
| `GET` | `/v1/webhook-endpoints` | List every active webhook endpoint in the workspace. Returns an array of { id, name, description, isActive, createdAt, updatedAt }. Use the `id` from any item as `endpointId` for agntdata_webhooks_get_endpoint, agntdata_webhooks_delete_endpoint, or agntdata_webhooks_list_deliveries. Use this to discover existing endpoints before creating a new one or to show the user their current webhook configuration. |
| `GET` | `/v1/webhook-endpoints/{id}` | Get full details of a single webhook endpoint by id. Returns { id, name, description, isActive, createdAt, updatedAt }. Use this when you have an endpoint id (e.g. from agntdata_webhooks_list_endpoints) and need its full record. Note: this does NOT return the receive URL — reconstruct it as https://api.agntdata.dev/webhooks/ingest/{id} if you need to show it again. |
| `DELETE` | `/v1/webhook-endpoints/{id}` | Soft-delete (deactivate) a webhook endpoint by id. After deletion the receive URL https://api.agntdata.dev/webhooks/ingest/{id} stops accepting POSTs (returns 404). Existing delivery history is retained and still queryable. Use this when the user wants to stop receiving events on an endpoint or rotate to a new one. ALWAYS confirm with the user
...[truncated 24 chars]
Confidence
95% confidence
Finding
The endpoint summary explicitly offers public URLs for arbitrary vendors and reconstructable receive URLs, while treating URL knowledge as authentication. In a skill advertised for social data, this broad inbound capability materially raises risk because it can capture and persist unrelated sensitive events and expose agents to forged input.

External Transmission

Medium
Category
Data Exfiltration
Content
|--------|------|---------|
| `POST` | `/v1/webhook-endpoints` | Create a new agntdata webhook endpoint. Returns { id, name, url } where `url` is a public HTTPS endpoint of the form https://api.agntdata.dev/webhooks/ingest/<id>. Give that URL to a third party (Stripe, Calendly, GitHub, your own service, etc.) so they can POST events to it. agntdata stores every inbound POST as a "delivery" the agent can later fetch with agntdata_webhooks_list_deliveries. The `name` is a workspace-unique label (3-50 chars, lowercase + hyphens) that you can show to the user; it is NOT part of the receive URL. Use this when the user asks to "set up a webhook", "give me a URL to receive events", or "let me ingest events from <vendor>". |
| `GET` | `/v1/webhook-endpoints` | List every active webhook endpoint in the workspace. Returns an array of { id, name, description, isActive, createdAt, updatedAt }. Use the `id` from any item as `endpointId` for agntdata_webhooks_get_endpoint, agntdata_webhooks_delete_endpoint, or agntdata_webhooks_list_deliveries. Use this to discover existing endpoints before creating a new one or to show the user their current webhook configuration. |
| `GET` | `/v1/webhook-endpoints/{id}` | Get full details of a single webhook endpoint by id. Returns { id, name, description, isActive, createdAt, updatedAt }. Use this when you have an endpoint id (e.g. from agntdata_webhooks_list_endpoints) and need its full record. Note: this does NOT return the receive URL — reconstruct it as https://api.agntdata.dev/webhooks/ingest/{id} if you need to show it again. |
| `DELETE` | `/v1/webhook-endpoints/{id}` | Soft-delete (deactivate) a webhook endpoint by id. After deletion the receive URL https://api.agntdata.dev/webhooks/ingest/{id} stops accepting POSTs (returns 404). Existing delivery history is retained and still queryable. Use this when the user wants to stop receiving events on an endpoint or rotate to a new one. ALWAYS confirm with the user before deleting — third par
...[truncated 26 chars]
Confidence
95% confidence
Finding
The deliveries API returns rawPayload, headers, and sourceIp for anything posted to the public ingest URL, effectively exposing a stored stream of unverified inbound data to the agent. This is dangerous because agents may parse or act on attacker-controlled content under the guise of webhook events.

External Transmission

Medium
Category
Data Exfiltration
Content
[
  {
    "name": "agntdata_webhooks_create_endpoint",
    "description": "Create a new agntdata webhook endpoint. Returns { id, name, url } where `url` is a public HTTPS endpoint of the form https://api.agntdata.dev/webhooks/ingest/<id>. Give that URL to a third party (Stripe, Calendly, GitHub, your own service, etc.) so they can POST events to it. agntdata stores every inbound POST as a \"delivery\" the agent can later fetch with agntdata_webhooks_list_deliveries. The `name` is a workspace-unique label (3-50 chars, lowercase + hyphens) that you can show to the user; it is NOT part of the receive URL. Use this when the user asks to \"set up a webhook\", \"give me a URL to receive events\", or \"let me ingest events from <vendor>\".",
    "method": "POST",
    "path": "/v1/webhook-endpoints",
    "parameters": {
Confidence
94% confidence
Finding
The tool schema formalizes creation of public ingest URLs for arbitrary third parties without requiring any sender verification, turning the skill into general-purpose webhook infrastructure. In an agent ecosystem this is particularly risky because schemas make misuse easy and normalize processing attacker-controlled payloads as tool outputs.

External Transmission

Medium
Category
Data Exfiltration
Content
},
  {
    "name": "agntdata_webhooks_list_deliveries",
    "description": "Fetch the most recent webhook deliveries for the workspace, newest first. This is THE tool to use to \"check for new webhook events\", \"process incoming webhooks\", or \"see what a third party sent\". Returns { deliveries: [{ id, webhookEndpointId, rawPayload, headers, sourceIp, acknowledgedAt, createdAt }], nextCursor }. `rawPayload` is the exact JSON body the third party POSTed to https://api.agntdata.dev/webhooks/ingest/<id> — parse it the way that vendor documents (e.g. for Stripe inspect `type` and `data.object`). Workflow: (1) call this with `unacknowledged: true` to get only un-processed deliveries, (2) handle each `rawPayload`, (3) call agntdata_webhooks_ack_delivery (or agntdata_webhooks_ack_deliveries for batch) with the delivery `id`s so they don't come back next poll. If `nextCursor` is non-null, pass it as `cursor` on the next call to page through older deliveries.",
    "method": "GET",
    "path": "/v1/webhook-endpoints/deliveries",
    "parameters": {
Confidence
95% confidence
Finding
The list-deliveries schema exposes exact raw POST bodies, headers, and source IPs from a public ingress endpoint to the agent, with no mention of authenticity or sanitization. That combination creates a high-risk path for spoofed data ingestion, privacy exposure, and unsafe automation based on attacker-controlled content.

External Transmission

Medium
Category
Data Exfiltration
Content
-H "Authorization: Bearer $AGNTDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "stripe-prod", "description": "Stripe events for production"}'
# => { "success": true, "data": { "id": "…", "name": "stripe-prod", "url": "https://api.agntdata.dev/webhooks/ingest/…" } }
```

Poll for new deliveries on that endpoint:
Confidence
93% confidence
Finding
The example response shows that the service returns a publicly usable ingest URL and encourages the user to distribute it, while the URL itself serves as the only authenticator. This makes accidental leakage or log exposure of the URL equivalent to compromise of the webhook endpoint.

External Transmission

Medium
Category
Data Exfiltration
Content
Poll for new deliveries on that endpoint:

```bash
curl "https://api.agntdata.dev/v1/webhook-endpoints/deliveries?unacknowledged=true&endpointId=$ENDPOINT_ID&limit=50" \
  -H "Authorization: Bearer $AGNTDATA_API_KEY"
```
Confidence
92% confidence
Finding
Polling and retrieving unacknowledged deliveries exposes the agent to raw untrusted payloads from the public ingest endpoint. In this context, the danger is not the GET request itself but that the documented workflow normalizes processing arbitrary inbound content without prior validation.

Static analysis

No suspicious patterns detected.