T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/sse_inbox.py:80
- Finding
- Authentication Token Can Be Transmitted Over Plaintext HTTP## Vulnerability Details **File Location**: `scripts/sse_inbox.py:80-94`; related insecure configuration guidance at `SERVER.md:44-48` **Vulnerability Type**: Transmission of authentication credentials over an unencrypted channel **Risk Level**: Medium ### Vulnerable Code ```python base_url = cfg["base_url"].rstrip("/") token = cfg["token"] stream_url = base_url + "/stream" try: import requests except ImportError: print("requests is required: pip install requests") sys.exit(1) headers = {"X-Token": token, "Accept": "text/event-stream"} log_channel("SSE_CONNECT_START") try: r = requests.get(stream_url, headers=headers, stream=True, timeout=60) r.raise_for_status() ``` Related documentation explicitly permits an HTTP endpoint: ```markdown 3. Access API docs at `http://YOUR_HOST:8000/docs` 4. Set `base_url` in `../openwechat_im_client/config.json` to your server, e.g.: - Local: `http://localhost:8000` - Self-hosted: `https://your-domain.com:8000` ``` ### Technical Analysis The SSE client reads an unrestricted, user-configured `base_url` and sends the authentication token in the `X-Token` request header. It neither validates the URL scheme nor limits plaintext HTTP to loopback destinations. The token functions as a bearer credential for authenticated relay operations. When a non-loopback HTTP URL is configured, the header and all relay traffic are transmitted without transport encryption. An attacker capable of observing or modifying traffic between the client and relay can recover the token. Sending the token to the configured relay is necessary for the declared IM functionality. However, allowing the credential to be sent over plaintext HTTP to arbitrary network hosts exceeds secure minimum requirements. Plaintext HTTP should only be accepted for strictly local loopback development. ### Attack Path 1. A user configures a remote relay using an HTTP URL, such as `h ...[truncated 1256 chars]
- Remediation
- ## Remediation Suggestions 1. Parse `base_url` before constructing or sending any request. 2. Require the `https` scheme for all non-loopback destinations. 3. Permit plaintext HTTP only when the normalized hostname is exactly `localhost`, `127.0.0.1`, or `::1`. 4. Reject URLs containing unexpected credentials, malformed hostnames, or unsupported schemes. 5. Keep TLS certificate verification enabled and do not introduce `verify=False`. 6. Display a clear error explaining that authentication tokens cannot be sent to remote HTTP endpoints. 7. Update `SERVER.md`, `SKILL.md`, and the API examples so that remote deployments consistently require HTTPS. 8. Restrict `config.json` permissions to the current user and provide a documented token-rotation procedure after suspected exposure. Example validation approach: ```python from urllib.parse import urlparse parsed = urlparse(base_url) loopback_hosts = {"localhost", "127.0.0.1", "::1"} if parsed.scheme != "https": if parsed.scheme != "http" or parsed.hostname not in loopback_hosts: raise ValueError( "HTTPS is required unless the relay is hosted on a loopback address." ) ```
