Skip to content

Control server (--control) accepts unauthenticated commands, including file.saveAs to any path #34

Closed

Description

@Seronsecurity

Summary

When WordCraft is started with --control <port> (or WORDCRAFT_CONTROL_PORT), apps/wordcraft/src/control_server.rs listens on 127.0.0.1:<port> and runs every JSON line it receives as an engine command. There is no token or other authentication, so any local process can drive the app. The command set includes file.saveAs, file.exportPdf and file.exportPng with arbitrary paths, which means any local process can write files anywhere the user can.

The server is opt-in and loopback-only, so this is low severity. I'm reporting it as defense in depth, because the feature exists so agents can use it and people may leave it running.

Browser reachability

serve() replies bad JSON to a line it can't parse and then keeps reading the connection. An HTTP request therefore isn't rejected: its request line and headers fail to parse, and a body such as

\n{"method":"file.saveAs","params":{"path":"..."}}\n

is still executed. A web page could send that with fetch("http://127.0.0.1:<port>/", {method: "POST", mode: "no-cors", body}). Recent Chromium Local Network Access checks block many of these requests, but not every browser or version does, and the port is often predictable.

Suggested fixes

  1. Require a per-launch random token, printed to stderr or written to a 0600 file, sent as the first line or in each request, and have wordcraft mcp --connect pass it along.
  2. Close the connection on the first line that isn't valid JSON, or reject anything that looks like HTTP (GET , POST , Host:). This kills the cross-protocol vector.
  3. Optionally, by default, gate file-system commands (file.open, file.save*, file.export*, insert.picture with path, mail-merge recipients from a path) behind a flag.

Related, minor

Ctrl/Cmd+click on a hyperlink (crates/ui-egui/src/canvas.rs, around line 511) passes any URL to ctx.open_url without checking the scheme. Allowing only http, https and mailto, or confirming before anything else, would stop a document from launching file:// or custom-scheme handlers.

Thanks for the project. The rest of the code I looked at (build scripts, zip limits, unsafe_code = "forbid") looked solid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions