T09 · Insecure Skill Coding Practices
- Location
references/macro_format.md:82- Finding
Plaintext unauthenticated MCP transport exposes password-bearing HID macro configuration
- Content
View full analysis
Vulnerability Details
File Location:
references/macro_format.md:82-85
Related Locations:references/device_setup.md:34-50,SKILL.md:23,index.js:915-925,dsh-plugin/patch.yml:10
Vulnerability Type: Plaintext transmission of sensitive data and unauthenticated device control
Risk Level: HighComplete Evidence
references/macro_format.md:82-85documents sending a plaintext password as part of a macro:markdown ### password Type a password stored in encrypted hardware NVS. Stored/queried macros show `*` of identical length. - `{"password": "Abc123"}` — plain passwordreferences/device_setup.md:34-50directs clients to use an unencrypted HTTP MCP endpoint without documenting authentication:markdown ## MCP endpoint Once the device is on the same network, its MCP endpoint is:http://<device-name>.local:18791/mcp
text Add the server to your agent config. For opencode, edit `~/.config/opencode/opencode.json`: ```jsonc { "mcp": { "workled": { "type": "remote", "url": "http://<device-name>.local:18791/mcp", "enabled": true } } }SKILL.md:23exposes the macro mutation operation:markdown | set_macro | macro_name: string, macro_json: string | Set the macro for a touch pad gesture; macro_name ∈ `single_click`/`double_click`/`long_press`; macro_json is a JSON array of segments (see Macro Format); empty macro_json resets | `set_macro("single_click", '[{"combo":"ctrl+c"}]')` |The bundled client’s request implementation in
index.js:915-925supplies content negotiation headers but no authentication credentials:javascript async function postJson(url, method, params, controller, extraHeaders = {}) { const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", ...extraHeaders, ...[truncated 3410 chars]- Remediation
View remediation
Remediation Suggestions
- Require HTTPS for the MCP endpoint and validate the device certificate or a pinned device identity.
- Require per-device authentication for every MCP request, especially
set_macroand other state-changing tools. Use a securely provisioned token, mutual TLS, or a cryptographic challenge-response protocol. - Do not provision reusable passwords as plaintext JSON fields over the network. Prefer device-local secret enrollment or application-specific tokens with restricted scope.
- If remote secret provisioning is unavoidable, encrypt the secret for the authenticated device before transmission and prevent it from appearing in agent transcripts, logs, diagnostics, or error messages.
- Separate low-risk LED-state operations from sensitive HID macro administration. Apply stronger authorization and explicit user confirmation to macro changes.
- Bind the device management endpoint to trusted interfaces and reject requests from unauthenticated LAN clients.
- Update
references/device_setup.md,references/macro_format.md, and generated client configurations so insecure HTTP password provisioning is not presented as the default workflow. - Add integration tests verifying that unauthenticated macro mutation is rejected and that password-bearing requests cannot be sent over plaintext transport.
