T09 · Insecure Skill Coding Practices
- Location
notify.py:269- Finding
Transcript-Derived Data and Authentication Credentials May Be Sent over Plaintext WebSocket
- Content
View full analysis
Vulnerability Details
File Location:
notify.py:269-285,notify.py:467-481;SKILL.md:31-32
Vulnerability Type: Plaintext transmission of sensitive information to an unrestricted endpoint
Risk Level: HighVulnerable Code
python ws = await asyncio.wait_for( websockets.connect(cfg["url"], proxy=cfg.get("proxy")), timeout ) hello = { "mac": cfg["device_id"], "code": cfg["auth_code"], "agent": cfg.get("agent", "unknown"), "host": os.uname().nodename, "v": 1, } await ws.send(json.dumps(hello))Transcript-derived task information is subsequently included in the outbound event:
python return { "type": "task_status", "agent": agent, "task": task, "status": status, "time": dt.isoformat(timespec="seconds"), "detail": detail, "text": TEMPLATE.format( agent=AGENT_CN.get(agent, agent), task=task, status=STATUS_CN.get(status, status), time=_spoken_time(dt), ), }The documented setup example permits a plaintext endpoint:
bash python3 <SKILL_DIR>/notify.py setup \ --url ws://192.168.1.10:9004/agent/notify \ --device-id aa:bb:cc:dd:ee:ff \ --auth-code XXXXTechnical Analysis
The application accepts an arbitrary WebSocket URL and does not require the encrypted
wss://scheme. During connection establishment, it sends the authorization code, device identifier, detected agent name, and local hostname. Later status frames contain task text extracted from agent conversation records.When
ws://is used, WebSocket traffic has no transport-layer confidentiality or integrity. A network-positioned attacker can observe or modify authentication and notification frames. The unrestricted destination also means that a user who is induced to configure an attacker-controlled endpoint will disclose the same data directly to that endpoint.Certificat ...[truncated 1357 chars]
- Remediation
View remediation
Remediation Suggestions
- Require
wss://for all non-loopback destinations and reject plaintext remote endpoints. - Retain normal TLS certificate and hostname verification.
- Optionally support explicit certificate or public-key pinning for private deployments.
- Display the destination and a preview of the information that will be transmitted before enabling monitoring.
- Use narrowly scoped, short-lived, revocable credentials rather than reusable authorization codes.
- Bind credentials to the intended device on the server and apply replay protection.
- Redact common secret formats and sensitive identifiers from task text before transmission.
- Provide a mode that transmits only a user-supplied task label and status, without conversation-derived text or hostname metadata.
- Require
