T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/omie_webhook.py:12
- Finding
- Webhook Receiver Accepts Unauthenticated Events on All Network Interfaces## Vulnerability Details **File Location**: `scripts/omie_webhook.py`, lines 12-15 and 64-70 **Vulnerability Type**: Unauthenticated webhook endpoint and insecure default network exposure **Risk Level**: High **Vulnerable Code**: ```python def do_POST(self): """Handle POST requests from Omie.""" content_length = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(content_length) ``` ```python def main(): """Start the webhook receiver.""" parser = argparse.ArgumentParser(description='Omie ERP Webhook Receiver') parser.add_argument('--port', type=int, default=8089, help='Port to listen on') parser.add_argument('--host', default='0.0.0.0', help='Host to bind to') args = parser.parse_args() server_address = (args.host, args.port) httpd = HTTPServer(server_address, OmieWebhookHandler) ``` ### Technical Analysis The receiver binds to `0.0.0.0` by default, making it reachable through every network interface permitted by host and firewall configuration. The POST handler accepts JSON without validating a cryptographic signature, shared secret, source identity, request path, timestamp, or unique event identifier. Consequently, any party able to reach the port can construct an arbitrary JSON document, assign any value to its `event` field, and have it treated and logged as a successfully received event. The endpoint returns HTTP 200 after parsing the JSON, regardless of whether the request originated from Omie. The current code only logs received events and does not itself modify ERP records. Nevertheless, fabricated events undermine the integrity of the receiver's logs and could be incorrectly trusted by external log consumers or future downstream integrations. ### Attack Path 1. The operator launches the receiver with its documented defaults. 2. The process binds TCP port 8089 to `0.0.0.0`. 3. An attacker with network access connects to the ...[truncated 876 chars]
- Remediation
- ## Remediation Suggestions 1. Bind to `127.0.0.1` by default and require an explicit option to expose the listener externally. 2. Implement Omie's supported webhook authentication or signature-verification mechanism. Verify the signature over the raw request body before parsing or processing it. 3. If a shared secret is used, store it in an environment variable or secret manager and compare authentication values with a constant-time function such as `hmac.compare_digest`. 4. Validate timestamps and unique event identifiers to reject stale or replayed requests. 5. Restrict requests to a dedicated webhook path and reject unsupported methods, paths, content types, and event types. 6. Place the receiver behind a production HTTPS reverse proxy with firewall rules, rate limiting, and source restrictions where Omie publishes reliable source ranges. 7. Do not regard source-IP filtering as a replacement for cryptographic request authentication.
