Back to skill

Security audit

Moralis Streams Api

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Moralis Streams purpose, but one runnable tutorial hard-codes a third-party webhook URL that could make a user's stream send monitoring data outside their control.

Install only if you trust the publisher/source and are comfortable reviewing API commands before they run. Replace any webhook.site, YOUR_WEBHOOK_URL, or placeholder destination with an HTTPS endpoint you own, confirm create/update/delete/patch/status/settings actions against live streams, and keep MORALIS_API_KEY in environment or local secret storage rather than chat. If a stream is accidentally created with the fixed webhook.site URL, pause or delete it in Moralis and recreate it with a controlled endpoint.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
references/Tutorials.md:12
Finding
Hard-Coded Third-Party Webhook Can Disclose Monitored Blockchain Events## Vulnerability Details **File Location**: `references/Tutorials.md`, lines 12–21 **Vulnerability Type**: Hard-coded external data destination **Risk Level**: Medium ### Vulnerable Code ```bash curl -X PUT "https://api.moralis-streams.com/streams/evm" \ -H "accept: application/json" \ -H "X-API-Key: $MORALIS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chainIds": ["0x38"], "description": "Listen to a list of wallets for BUSD transfers", "tag": "busd-transfers", "webhookUrl": "https://webhook.site/e04c2edc-afb9-45b8-aff5-20724b2b1561", "includeContractLogs": true, ``` ### Technical Analysis The runnable tutorial configures a Moralis stream with a fixed `webhook.site` URL rather than a clear user-controlled placeholder. Moralis will send matching stream events to the configured webhook destination. This destination is not required for the Skill's declared functionality and exceeds least-data-disclosure expectations: the user must provide a webhook endpoint, but it does not need to be this specific externally controlled endpoint. Other project examples correctly use placeholders such as `https://YOUR_WEBHOOK_URL` or `https://your-server.com/webhook`. The API key is sent only to the declared Moralis API and is not directly disclosed to `webhook.site`. However, the stream's resulting webhook payloads are delivered to the hard-coded destination. Once wallet addresses are added in the tutorial's next step, those payloads may reveal monitored addresses, matched transactions, transfer values, contract addresses, block information, and related event metadata. ### Attack Path 1. A user or agent follows the tutorial without replacing the hard-coded webhook URL. 2. The command uses the user's `MORALIS_API_KEY` to create an authenticated Moralis stream. 3. The stream is configured to deliver matching BUSD transfer events to the fixed `webhook.site` endpoint. 4. The user follows the next tu ...[truncated 983 chars]
Remediation
## Remediation Suggestions 1. Replace the fixed URL with an unmistakable placeholder: ```json "webhookUrl": "https://YOUR_WEBHOOK_URL" ``` 2. Add an instruction immediately before the command requiring users to replace the placeholder with an HTTPS endpoint they own and control. 3. Instruct the agent not to create a stream until the user has explicitly confirmed the webhook destination. 4. Warn users not to use shared or public webhook-inspection services for production, personal, or otherwise sensitive monitoring. 5. Validate the destination before stream creation: - Require HTTPS. - Reject known example or public collector URLs by default. - Display the destination hostname and request confirmation. - Avoid embedding credentials or sensitive query parameters in the URL. 6. Add a post-creation safety check that reports the configured destination and explains how to pause, update, or delete an accidentally created stream. 7. Review future runnable examples for fixed external destinations and use non-routable placeholders consistently.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (110)

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
f",
      "topic1": "0x0000000000000000000000000a46413965858a6ac4ed5184d7643dc055a4fea3",
      "topic2": "0x000000000000000000000000e496601436da37a045d8e88bbd6b2c2e17d8fe33",
      "topic3": null
    }
  ],
  "txs": [
    {
      "hash": "0x1642a3b9b39e63d7fe571e7c22b80a5b059d2647fe4866d3f7105630f822d833",
      "gas": "85359",
      "gasPrice": "6129141152",
      "nonce": "88",
      "input": "0xa9059cbb000000000000000000000000e496601436da37a045d8e88bbd6b2c2e17d8fe330000000000000000000000000000000000000000000069e10006afc3291c0000",
      "transactionIndex": "49",
      "fromAddress": "0x0a46413965858a6ac4ed5184d7643dc055a4fea3",
      "toAddress": "0x0041ebd11f598305d401cc1052df49219630ab79",
      "value": "0",
      "type": "2",
      "v": "1",
      "r": "86947778944630951418310264989677611886333891146913483133255814972120449355054",
      "s": "7019311275916215306620036726907048105130260362064080269753410507440852031640",
      "receiptCumulativeGasUsed": "11882265",
      "rece
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The manifest says the skill is for real-time event monitoring and explicitly says it is NOT for querying historical or current blockchain state, directing such use to a different skill. This file exposes `/history/logs` and describes getting all logs, which is a historical retrieval capability outside that stated scope.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### API Key (optional)

**Never ask the user to paste their API key into the chat.** Instead:

1. Check if `MORALIS_API_KEY` is set in the environment (try running `[ -n "$MORALIS_API_KEY" ] && echo "API key is set" || echo "API key is NOT set"`).
2. If not set, offer to create the `.env` file with an empty placeholder: `MORALIS_API_KEY=`
Confidence
80% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
WEBHOOK_URL="https://your-server.com/webhook"

# List streams (requires limit)
curl "https://api.moralis-streams.com/streams/evm?limit=100" \
  -H "X-API-Key: $MORALIS_API_KEY"

# Create stream (PUT, not POST)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Example: Create ERC20 Transfer Monitor

```bash
curl -X PUT "https://api.moralis-streams.com/streams/evm" \
  -H "X-API-Key: $MORALIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The webhook signature verification example is security-sensitive but presents a simplistic construction (`sha3(body + secret)`) as if it were sufficient, without caveats about using the provider’s exact signing scheme, constant-time comparison, canonical raw-body handling, replay protection, or a standard MAC such as HMAC if required by the platform. In a webhook-focused skill, users are likely to copy this snippet directly, which can result in forged webhook acceptance or broken verification if the body is reserialized differently from the originally signed payload.

External Transmission

Medium
Category
Data Exfiltration
Content
**5 requests per 5 minutes** for address addition endpoints. To stay within limits, use batch operations — send multiple addresses in a single request using the `addressToAdd` array (up to 50,000 addresses per batch).

```bash
curl -X POST "https://api.moralis-streams.com/streams/evm/STREAM_ID/address" \
  -H "X-API-Key: $MORALIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"addressToAdd": ["0x1234...", "0x5678...", "0x9abc..."]}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Create Stream: All ERC20 Transfers

```bash
curl -X PUT "https://api.moralis-streams.com/streams/evm" \
  -H "X-API-Key: $MORALIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Request

```bash
curl -X POST "https://api.moralis-streams.com/streams/evm/{streamId}/address" \
  -H "accept: application/json" \
  -H "X-API-Key: $MORALIS_API_KEY" \
  -H "Content-Type: application/json" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation includes DELETE and PATCH examples that remove or replace addresses on an existing stream, but it does not clearly warn that these operations are state-changing and can immediately alter production monitoring coverage. A user following the examples against a live stream could unintentionally stop monitoring important addresses or overwrite the entire address set, causing loss of visibility and operational security gaps.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The stream creation example sends blockchain event data to a user-supplied webhook URL but provides no warning about securing that endpoint or the sensitivity of monitored activity. This can lead users to forward wallet activity and contract events to improperly protected or third-party endpoints, risking data exposure, spoofing, or insecure ingestion pipelines.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -X GET \
  "https://api.moralis-streams.com/history/logs?limit=100&streamId=YOUR_STREAM_ID&deliveryStatus=failed" \
  -H "X-API-Key: $MORALIS_API_KEY"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/WebhookSecurity.md:54