T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/chatgpt_image_tailnet.py:13
- Finding
- Unauthenticated Remote Browser Control over Plain HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chatgpt_image_tailnet.py`, lines 13-27 **Vulnerability Type**: Remote browser API lacking application-level authentication and TLS **Risk Level**: High ### Complete Code Snippet ```python DEFAULT_BASE = "http://100.89.48.48:9377" CHATGPT_URL = "https://chatgpt.com/" def request(base, method, path, params=None, body=None, timeout=60): url = base.rstrip("/") + path if params: url += "?" + urllib.parse.urlencode(params) data = None headers = {"Content-Type": "application/json"} if body is not None: data = json.dumps(body).encode() req = urllib.request.Request(url, data=data, headers=headers, method=method) with urllib.request.urlopen(req, timeout=timeout) as resp: raw = resp.read().decode() return json.loads(raw) if raw else {"ok": True} ``` ### Technical Analysis The default browser-control endpoint uses plain HTTP, and requests contain no authorization token, client certificate, request signature, or other application-level authentication mechanism. The API is used for sensitive operations including creating browser tabs, reading page snapshots, entering user prompts, executing JavaScript in an authenticated page, and retrieving downloaded files. The endpoint is a private Tailscale address, which limits ordinary Internet exposure and normally provides encrypted transport between authorized tailnet nodes. However, tailnet membership alone does not create endpoint-level authorization. A compromised or excessively privileged tailnet peer could potentially connect directly to the service if Tailscale ACLs or host firewall rules do not restrict it. Plain HTTP also leaves the application without independent TLS identity verification or protection if the endpoint is accessed outside the expected protected tunnel. The `--base` option can redirect all browser-control traffic to an arbitrary HTTP endpoint. Because server responses are trusted ...[truncated 1905 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Serve the browser API over HTTPS and validate the server certificate. For private infrastructure, use a private CA or mutually authenticated TLS. 2. Require a scoped API credential for every request. Avoid relying exclusively on possession of tailnet access. 3. Limit the credential to the required operations and browser profile. In particular, tightly restrict the general-purpose JavaScript evaluation endpoint. 4. Configure Tailscale ACLs and the remote host firewall so only the specific automation host can reach port `9377`. 5. Bind the service to the narrowest appropriate network interface and avoid exposing it on public or unrelated private interfaces. 6. Validate `--base` against an explicit allowlist of trusted HTTPS origins, or require a deliberate override before connecting to a non-allowlisted endpoint. 7. Do not place credentials in command-line arguments. Load them from a protected secret store or environment variable and send them through an authorization header. 8. Add server-side audit logging, request rate limits, credential rotation, and alerts for unexpected clients or sensitive browser operations. ]]>
