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
-
Binary-safe image round-trip (
server.mjs). The stdio MCP server's
get_imagetool used to decode every response as UTF-8 text, then
reconstruct it as binary viaBuffer.from(text, "binary"). Any byte
>= 0x80that wasn't part of a valid multi-byte UTF-8 sequence was
corrupted.httpJsonnow returns rawBuffers; callers that need
a string decode themselves, andget_imagebase64-encodes the buffer
directly. Thestatus >> 400typo incallCheckQueueis also fixed
(should be>=). -
No-redirect auth policy (
submit_workflow.py+server.mjs).
urllib.request.urlopenfollows redirects while retaining the
Authorization: Bearerheader. A redirected endpoint — proxy
misconfig, DNS hijack, accidental public URL — could receive the
token. Both clients now install a_NoRedirectHandlersubclass that
overrideshttp_error_301/302/303/307/308to raise, so the
cross-origin token-forward path is closed. The default
HTTPRedirectHandleris stripped from bothopener.handlers(legacy
list) andopener.handle_error[protocol][code](the actual dispatch
dict — this was the gotcha that bit the first iteration of the fix). -
All 4 marker substitutions implemented (
submit_workflow.py).
The docs promised__PROMPT__/__TRIGGER__/__IMAGE1__/
__IMAGE2__and the corresponding--prompt/--trigger/
--filename/--filename2CLI flags, but only__PROMPT__was
wired.apply_marker_substitutionnow 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. -
Output-path containment (
submit_workflow.py).out_dir / filenamejoined the server-supplied filename directly, so absolute
paths or../could escape--output-dir. Newsafe_join_under
rejects empty / NUL / POSIX-absolute / Windows-drive-rooted / parent-
traversal names. Used in bothcmd_downloadand the post-success
poll loop; a malicious filename from the server is logged and
skipped, but the rest of the run still completes. -
Workflow marker wiring. scenario 3 (
flux2-klein-image-edit.json)
had its image marker on an orphanLoadImage(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.mdAuthentication 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
--helplists 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_underaccepts 3 valid names + rejects 8 malicious ones- Redirect handler refuses 302 with the offending
Locationsurfaced
in theHTTPErrormessage - Binary round-trip preserves
0xC3 0xA9 0xFFbyte-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 neededThe version in plugin.json is 0.2.0-beta.2.