T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/relay-send.cjs:42
- Finding
- Relay credentials and message contents are transmitted over unauthenticated plaintext TCP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/relay-send.cjs:42-54`; protocol documented at `SKILL.md:139` **Vulnerability Type**: Plaintext transmission of sensitive information **Risk Level**: High ### Complete Code Snippet ```javascript const sock = net.createConnection({ host: HOST, port: PORT }, () => { sock.write(frame({ v: 1, type: 'HELLO', id: `${AGENT}-${Date.now()}`, ts: Date.now(), payload: { agent: AGENT, version: '1.0.0', authToken: TOKEN } })); }); const dec = new Decoder(); sock.on('data', (data) => { for (const f of dec.push(data)) { if (f.type === 'WELCOME') { sock.write(frame({ v: 1, type: 'SEND', id: `m-${Date.now()}`, ts: Date.now(), to: TO, payload: { kind: 'message', body: BODY } })); console.log(JSON.stringify({ ok: true, to: TO, body: BODY })); ``` The corresponding documentation explicitly identifies the transport as TCP: ```markdown **Protocol:** TCP, 4-byte big-endian length prefix + JSON payload (legacy framing) ``` ### Technical Analysis The script uses Node.js `net.createConnection`, which establishes a raw TCP connection without TLS encryption or server authentication. The initial `HELLO` frame contains the relay authentication token, while the subsequent `SEND` frame contains the recipient and message body. Consequently, any party able to observe or alter traffic between the client and relay can read the token and message, modify frames, or impersonate the relay. The destination is also configurable through `--host` and `X402_RELAY_HOST`, so a configuration error or manipulated invocation can send the credential directly to an attacker-controlled server. Network communication is necessary for the declared relay functionality, but transmitting reusable credentials and message contents without transport protection is not the minimum safe privilege required. ### Attack Path 1. A user invokes the relay script with a valid relay token. 2. The script opens a plaintext TCP connec ...[truncated 963 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Replace `net.createConnection` with `tls.connect`. - Require strict certificate-chain and hostname validation; do not disable `rejectUnauthorized`. - Pin the expected relay hostname or enforce an explicit allowlist of approved relay destinations. - Do not transmit authentication material until the TLS connection and peer identity have been successfully verified. - Prefer short-lived, audience-bound, least-privilege relay tokens. - Add clear failure handling so the script refuses to fall back to plaintext TCP. - If the relay cannot support TLS directly, use a mutually authenticated secure tunnel rather than exposing credentials over raw TCP. ]]>
