T09 · Insecure Skill Coding Practices
- 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.
