T09 · Insecure Skill Coding Practices
Warning
- Location
- references/recipes.md:41
- Finding
- Hardcoded Plaintext WebSocket Endpoint in Voice Navigation Recipe<![CDATA[ ## Vulnerability Details **File Location**: `references/recipes.md:41-50` **Vulnerability Type**: Hardcoded plaintext ASR WebSocket endpoint **Risk Level**: Medium ### Vulnerable Code ```tsx <CAINavProvider onVoiceSubmit={async (text) => { await routeByIntent(text); }} onVoiceError={(err) => console.error(err)} longPressMs={200} wsUrl="ws://localhost:8765" > {children} </CAINavProvider>; ``` ### Technical Analysis The voice-navigation recipe assigns the ASR endpoint using a hardcoded `ws://localhost:8765` URL. The `ws://` scheme does not provide transport encryption or endpoint authentication. The example also provides no mechanism for authenticating the ASR service. This contradicts the project's own requirement in `references/guardrails.md:18`, which states that the WebSocket URL and ASR authentication must come from application configuration rather than hardcoded values. Because this file is an implementation recipe intended to be copied into generated applications, developers may deploy the pattern without validating the endpoint, enforcing secure transport, or authenticating the receiving service. Although the example points to localhost, a process under another user's control or a compromised local process may bind to the expected port. If developers replace the host but retain the plaintext scheme, network-positioned attackers may intercept or modify the WebSocket traffic. ### Attack Path 1. A developer copies the voice-navigation recipe into an application. 2. The application opens an unauthenticated plaintext connection to `ws://localhost:8765`. 3. An attacker-controlled or compromised local process listens on port `8765`, or the endpoint is changed to a remote host while retaining `ws://`. 4. The application connects to the untrusted service without validating its identity. 5. Voice-related data sent through the ASR channel may be observed, retained, or manipulated by the attacker. 6. Manipulated ASR responses may be ...[truncated 824 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Load the ASR endpoint from validated application configuration rather than embedding it in the recipe. 2. Require `wss://` for every non-local endpoint and reject plaintext transport in production. 3. Authenticate the ASR service using an appropriate short-lived credential or authenticated session mechanism. 4. Validate the configured URL against an explicit allowlist of trusted schemes and hosts. 5. Fail closed when the endpoint, transport security, or authentication configuration is absent or invalid. 6. Avoid placing reusable secrets directly in client-side source code. Obtain short-lived connection credentials from a trusted backend when necessary. 7. Validate ASR responses before passing them to `routeByIntent`, and require explicit user confirmation and authorization checks for sensitive actions. 8. Replace the recipe with a configuration-driven example, such as: ```tsx const asrUrl = getRequiredAsrWebSocketUrl(); if (isProduction && !asrUrl.startsWith('wss://')) { throw new Error('A secure ASR WebSocket endpoint is required'); } <CAINavProvider onVoiceSubmit={async (text) => { await routeByIntent(validateVoiceIntent(text)); }} onVoiceError={handleVoiceError} longPressMs={200} wsUrl={asrUrl} > {children} </CAINavProvider>; ``` ]]>
