Skip to content

v0.2.0-beta.2 — security-fix refresh

Latest

Choose a tag to compare

@antianqi antianqi released this 22 Aug 19:01

v0.2.0-beta.2 — security-fix refresh

Closes the 5 blocking review defects from MiniMax-AI/MiniMax-Code-Plugins#15.

This is a drop-in replacement for v0.2.0-beta.1. There are no new features — only
fixes. If you installed v0.2.0-beta.1, please re-install this version.

What's fixed

  1. Binary-safe image round-trip (server.mjs). The stdio MCP server's
    get_image tool used to decode every response as UTF-8 text, then
    reconstruct it as binary via Buffer.from(text, "binary"). Any byte
    >= 0x80 that wasn't part of a valid multi-byte UTF-8 sequence was
    corrupted. httpJson now returns raw Buffers; callers that need
    a string decode themselves, and get_image base64-encodes the buffer
    directly. The status >> 400 typo in callCheckQueue is also fixed
    (should be >=).

  2. No-redirect auth policy (submit_workflow.py + server.mjs).
    urllib.request.urlopen follows redirects while retaining the
    Authorization: Bearer header. A redirected endpoint — proxy
    misconfig, DNS hijack, accidental public URL — could receive the
    token. Both clients now install a _NoRedirectHandler subclass that
    overrides http_error_301/302/303/307/308 to raise, so the
    cross-origin token-forward path is closed. The default
    HTTPRedirectHandler is stripped from both opener.handlers (legacy
    list) and opener.handle_error[protocol][code] (the actual dispatch
    dict — this was the gotcha that bit the first iteration of the fix).

  3. All 4 marker substitutions implemented (submit_workflow.py).
    The docs promised __PROMPT__ / __TRIGGER__ / __IMAGE1__ /
    __IMAGE2__ and the corresponding --prompt / --trigger /
    --filename / --filename2 CLI flags, but only __PROMPT__ was
    wired. apply_marker_substitution now walks every node and replaces
    all four markers (exact-match only, so user prompts containing marker
    prefixes are left alone). Adds a warning for any marker left
    unresolved at submit time.

  4. Output-path containment (submit_workflow.py). out_dir / filename joined the server-supplied filename directly, so absolute
    paths or ../ could escape --output-dir. New safe_join_under
    rejects empty / NUL / POSIX-absolute / Windows-drive-rooted / parent-
    traversal names. Used in both cmd_download and the post-success
    poll loop; a malicious filename from the server is logged and
    skipped, but the rest of the run still completes.

  5. Workflow marker wiring. scenario 3 (flux2-klein-image-edit.json)
    had its image marker on an orphan LoadImage (node 81) while the
    actually-connected loader (node 76) was blank. Now: orphan removed,
    76.inputs.image = "__IMAGE1__". scenario 4 (flux2-klein-image- edit-dual.json) had blank loaders with no markers at all. Now:
    76 = "__IMAGE1__", 81 = "__IMAGE2__".

Documentation

  • docs/security-notes.md Authentication section rewritten to match the
    new no-redirect policy (the old text claimed the token "never leaves
    the host", which the implementation did not actually guarantee).

Verification

A new tests/test_fixes.py covers every blocker end-to-end. 34/34
PASS
across 7 test groups:

  • Node --check server.mjs
  • Python ast.parse submit_workflow.py
  • CLI --help lists all 4 flags
  • Workflow JSON shape + image marker wiring
  • Marker substitution (incl. negative case: a literal __PROMPT__
    inside user text is not substituted)
  • safe_join_under accepts 3 valid names + rejects 8 malicious ones
  • Redirect handler refuses 302 with the offending Location surfaced
    in the HTTPError message
  • Binary round-trip preserves 0xC3 0xA9 0xFF byte-for-byte through
    get_image

Install / upgrade

# fresh install
git clone https://github.com/antianqi/comfyui-studio.git
cd comfyui-studio
# the plugin is the whole repo root — symlink or copy into your plugins dir

# upgrade from v0.2.0-beta.1: replace the old folder, no config migration needed

The version in plugin.json is 0.2.0-beta.2.