T09 · Insecure Skill Coding Practices
- Location
scripts/webhook_server.py:38- Finding
Publicly Exposed Webhook Receiver Lacks Authentication and Request-Size Limits
- Content
View full analysis
Vulnerability Details
File Location:
scripts/webhook_server.py, lines 38–59 and line 174
Vulnerability Type: Unauthenticated webhook processing and unbounded request-body handling
Risk Level: MediumVulnerable Code
python def do_POST(self): """Handle webhook POST requests.""" if self.path == "/webhook/manus": content_length = int(self.headers.get("Content-Length", 0)) body = self.rfile.read(content_length) try: data = json.loads(body.decode("utf-8")) self.handle_manus_webhook(data) self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(b'{"status": "ok"}') except Exception as e: print(f"❌ Error processing webhook: {e}") self.send_response(400) self.end_headers() else: self.send_response(404) self.end_headers()python server = HTTPServer(("0.0.0.0", args.port), WebhookHandler)Technical Analysis
The HTTP server binds to
0.0.0.0, making it reachable through every available network interface unless external firewall rules prevent access. The webhook endpoint accepts JSON events without verifying a cryptographic webhook signature, shared secret, timestamp, source identity, or other proof that the request originated from Manus.The handler also converts the attacker-controlled
Content-Lengthheader to an integer and passes it directly toself.rfile.read()without enforcing a maximum request size. This permits excessive memory consumption and allows clients to hold the single-threaded server while slowly transmitting a declared request body.Attacker-controlled event fields—including task identifiers, titles, and error messages—are printed to the terminal without sanitizing control characters ...[truncated 1514 chars]
- Remediation
View remediation
Remediation Suggestions
- Bind to
127.0.0.1by default. Require an explicit command-line option to listen on public or non-loopback interfaces. - Verify the webhook provider's cryptographic signature over the raw request body. Reject requests with missing, malformed, stale, or invalid signatures, and use constant-time comparison where applicable.
- Add replay protection by validating a signed timestamp and rejecting events outside a short permitted time window. Track event identifiers if the provider supports them.
- Enforce a small maximum request-body size before calling
read(). Return HTTP413 Payload Too Largewhen the declared size exceeds the limit. - Configure connection and read timeouts. Consider a hardened, concurrent production HTTP server when public exposure is required.
- Require an appropriate JSON
Content-Typeand validate the event payload against a strict schema before processing it. - Sanitize carriage returns, newlines, escape sequences, and other terminal-control characters before printing remote fields.
- Place any externally reachable deployment behind a TLS-enabled reverse proxy with firewall rules, rate limiting, and request-size limits.
- Bind to
