T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- bot.py:39
- Finding
- Unauthenticated Public Webhook Permits Unauthorized Model API Usage## Vulnerability Details **File Location**: `bot.py:39-70` **Vulnerability Type**: Missing webhook authentication and request-integrity validation **Risk Level**: High ### Complete Code Snippet ```python @app.route("/webhook", methods=["POST"]) def webhook(): """处理飞书消息""" data = request.json # 验证请求 if data.get("type") == "url_verification": return {"challenge": data["challenge"]} # 解析消息 event = data.get("event", {}) message = event.get("message", {}) content = json.loads(message.get("content", "{}")) text = content.get("text", "") sender_id = event.get("sender", {}).get("sender_id", {}).get("open_id", "") # 调用 AI 生成回复 messages = [ {"role": "system", "content": "你是企业AI助手,用简洁专业的中文回答问题。"}, {"role": "user", "content": text} ] reply = call_openclaw(messages) # TODO: 调用飞书 API 发送回复 # 这里需要使用 lark SDK 发送消息 return {"success": True, "reply": reply} ``` The service is additionally exposed on all network interfaces at `bot.py:82`: ```python app.run(host="0.0.0.0", port=8080) ``` ### Technical Analysis The `/webhook` endpoint trusts every incoming JSON request. Although the code contains a request-verification comment, it only handles the Feishu URL-verification challenge and does not authenticate normal events. There is no verification of a webhook signature, verification token, encryption key, timestamp, nonce, source address, or event identifier. There is also no replay protection or rate limiting. Consequently, an attacker who can reach TCP port 8080 can construct a synthetic event containing arbitrary text. The application then forwards that text to the configured OpenClaw endpoint while authenticating with the server's `OPENCLAW_API_KEY`. Returning the model response directly also provides attackers with an unauthenticated model API proxy. The unused `sender_i ...[truncated 1529 chars]
- Remediation
- ## Remediation Suggestions 1. Validate every webhook using Feishu's documented signature, verification-token, or encrypted-event mechanism before reading or processing event content. 2. Store verification credentials in a secret manager or protected environment variables rather than trusting fields from the incoming request. 3. Validate timestamps and nonces and maintain a bounded cache of processed event identifiers to prevent replay attacks. 4. Reject requests with missing, malformed, stale, or invalid authentication data using an appropriate authorization error. 5. Apply per-source and global rate limits, request-size limits, model-token limits, and API spending controls. 6. Restrict network exposure through a firewall, reverse proxy, or API gateway. Do not directly expose Flask's development server. 7. Deploy through a production WSGI server with TLS termination, structured security logging, and alerting for repeated authentication failures. 8. Validate the event schema and ensure the sender and tenant are authorized before invoking the model.
