T09 · Insecure Skill Coding Practices
- Location
- scripts/setup_webhook.py:147
- Finding
- Unauthenticated webhook receiver exposes sensitive email payloads## Vulnerability Details **File Location**: `scripts/setup_webhook.py:147-175` **Vulnerability Type**: Unauthenticated network endpoint and sensitive-data logging **Risk Level**: Medium ### Vulnerable Code ```python @app.route('/webhook', methods=['POST']) def webhook(): payload = request.json print("\n🪝 Webhook received:") print(f" Event: {payload.get('event_type')}") print(f" ID: {payload.get('event_id')}") if payload.get('event_type') == 'message.received': message = payload.get('message', {}) print(f" From: {message.get('from', [{}])[0].get('email')}") print(f" Subject: {message.get('subject')}") print(f" Preview: {message.get('preview', '')[:50]}...") print(f" Full payload: {json.dumps(payload, indent=2)}") print() return Response(status=200) print("🚀 Starting webhook test server on http://localhost:3000") print("📡 Webhook endpoint: http://localhost:3000/webhook") print("\n💡 For external access, use ngrok:") print(" ngrok http 3000") print("\n🛑 Press Ctrl+C to stop\n") try: app.run(host='0.0.0.0', port=3000, debug=False) ``` ### Technical Analysis The bundled test receiver accepts webhook requests without verifying an AgentMail signature, authenticating the sender, validating the request content type, or limiting the request size. Binding Flask to `0.0.0.0` makes the endpoint reachable through every available network interface rather than only the local development host. The receiver also serializes the complete webhook payload to standard output. A legitimate `message.received` payload can contain sender and recipient addresses, subjects, email bodies, thread information, and attachment metadata. These values may consequently be disclosed to terminal history, container logs, service logs, or centralized logging systems. Although `references/WEBHOOKS.md` describes signature v ...[truncated 1619 chars]
- Remediation
- ## Remediation Suggestions 1. Bind the development server to `127.0.0.1` by default rather than `0.0.0.0`. 2. Require AgentMail webhook signature verification before parsing or processing a payload. 3. Calculate the signature over the raw request body and compare it using a constant-time function such as `hmac.compare_digest`. 4. Reject missing, malformed, expired, or invalid signatures with an appropriate error response. 5. Validate that the request uses the expected content type and enforce a conservative maximum request-body size. 6. Validate required fields and accepted event types before accessing nested data. 7. Do not log complete webhook payloads. Log only redacted event identifiers and operational metadata. 8. Redact email addresses, subjects, bodies, tokens, attachment data, and custom headers from logs. 9. Clearly mark tunneling through ngrok as unsafe unless authentication and signature verification have already been enabled. 10. Apply rate limiting and replay protection when the endpoint is exposed beyond localhost.
