T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/zynd_webhook_server.py:200
- Finding
- Unauthenticated Public Message Disclosure and Sender Spoofing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/zynd_webhook_server.py`, lines 25–27, 83–94, 128–139, 200–211, and 247–253 **Vulnerability Type**: Missing authentication and authorization on public webhook endpoints **Risk Level**: High ### Vulnerable Code ```python parser.add_argument( "--host", default="0.0.0.0", help="Host to bind to (default: 0.0.0.0)" ) ``` ```python @app.route("/webhook", methods=["POST"]) def handle_webhook(): """Handle async incoming messages.""" try: if not request.is_json: return jsonify( {"error": "Content-Type must be application/json"} ), 400 payload = request.get_json() message = AgentMessage.from_dict(payload) ``` ```python @app.route("/messages", methods=["GET"]) def list_messages(): """List received messages.""" with lock: return jsonify( { "count": len(received_messages), "messages": received_messages[-20:], # Last 20 } ), 200 ``` ```python app.run( host=args.host, port=args.port, debug=False, use_reloader=False, threaded=True, ) ``` ### Technical Analysis The webhook server binds to all interfaces by default. Its message-receiving endpoints accept any JSON payload that can be parsed by `AgentMessage.from_dict`, but the server does not authenticate the caller, validate a message signature, verify the supplied DID, enforce sender authorization, or prevent replay. The unauthenticated `GET /messages` endpoint returns the last 20 stored messages. Each stored record includes the complete serialized message, receipt time, and source IP address. Consequently, anyone who can connect to the service can retrieve potentially sensitive delegated task content and network metadata. The implementation also lacks request-size, rate, and message-retention limits. Because `received_messages` grows for the lifetime of the process, repeated valid su ...[truncated 1282 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Bind to `127.0.0.1` by default and require an explicitly configured trusted reverse proxy for external exposure. 2. Authenticate every webhook request using verifiable message signatures or a mutually authenticated transport. 3. Validate the supplied DID against the trusted Zynd identity service and verify that the message was signed by the corresponding identity. 4. Add timestamps, nonces, and replay detection. 5. Remove `/messages` in production. If operationally required, protect it with strong authentication and authorization and redact message content and source IPs. 6. Apply strict body-size limits, schema validation, per-source rate limits, and bounded message retention. 7. Use TLS at the server or reverse-proxy layer. 8. Return generic errors rather than exposing internal exception strings. ]]>
