diff --git a/SECURITY.md b/SECURITY.md index ffd46f2..2240c0f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -30,6 +30,11 @@ follows a few fixed rules. `scripts/release_preflight.py` fails a release whose shipped code contains an HTTP or socket client. +These rules protect a ComfyUI server from the requests it receives. They do +not defend against someone who can already change files on the ComfyUI +machine, and exposing ComfyUI beyond a trusted network is still a risk of +its own. + ## Reporting a vulnerability Report privately through this repository's **Security** tab → diff --git a/docs/registry_audit_2026-09-10.md b/docs/registry_audit_2026-09-10.md deleted file mode 100644 index e05e0ff..0000000 --- a/docs/registry_audit_2026-09-10.md +++ /dev/null @@ -1,82 +0,0 @@ -# Registry audit — 2026-09-10 - -The corrected source addresses the known endpoint and media-path risks. It -has not been published as a new version and has not been approved by the -Registry. The exact call site behind the older code-execution verdict is -still unconfirmed. - -## Recorded decisions - -Checked the Registry versions API with `include_status_reason=true` and -[review issue #216](https://github.com/Comfy-Org/registry-backend/issues/216). -The issue still contains only the publisher's two follow-ups, with no -maintainer response naming the code-execution call site. - -| Versions | Current status | Recorded concern | -| --- | --- | --- | -| 1.1.0 / 1.1.1 | Banned | LM Studio's workflow-controlled endpoint enables server-side requests to arbitrary hosts. | -| 1.2.0 / 1.3.0 | Banned | Code execution reachable through `/prompt` or an unauthenticated route; no file or call site identified. | -| 2.0.0 / 2.0.1 | Flagged | Five informational findings: completion audio, two graph connection helpers, Civitai HTTP, and the local-preview environment switch. | - -Source: [Registry version records](https://api.comfy.org/nodes/ausboss-nodes/versions?include_status_reason=true). - -## Concern-to-evidence map - -| Surface | Corrected behavior and evidence | -| --- | --- | -| LM Studio endpoint | Removed from runtime modules, mappings, frontend, and help in 2.0.0. The live candidate registers 35 mappings and no LM Studio node. | -| Save Image arbitrary output directory | Only relative subfolders under ComfyUI output are accepted. Absolute paths, traversal, UNC, and Windows drive/alternate-stream syntax are rejected. The folder route uses the same resolver. | -| Save Image filenames and captions | Check complete batch destinations before writing, including linked filenames, exact names, local prefixes, and caption sidecars. Regression tests and live requests leave outside sentinel files unchanged when symlinks point outside output. | -| Save Video | Check the prefix before core creates directories; check the final destination before encoding. A regression test proves an escaping symlink creates no outside directory and never invokes the encoder. | -| Local video files and previews | Both execution and preview routes enforce ComfyUI input/output/temp containment. The former environment switch grants no access. UNC input paths are refused before resolution. | -| Civitai HTTP | The sole backend HTTP feature uses a fixed HTTPS endpoint, validates cached/computed SHA-256 text, disables redirects, and refuses 3xx responses. Tests prove malformed hashes do not open a session and redirects cannot trigger a second request or metadata write. Lookup sends the model hash, not model contents. | -| Completion sound | A generated in-memory WAV replaces WebAudio connections. The browser decodes and plays the 0.72-second chime after a user gesture; no audio asset or remote fetch is needed. | -| Recreate / replace-missing `.connect()` | Retained: these are LiteGraph workflow-link operations, not sockets. Tests cover the graph behavior. They may still match the Registry's broad informational rule. | -| Math expression | Existing allowlisted AST evaluator remains; it does not evaluate Python source. Its malicious-input regression tests pass. | -| Archive tooling/test findings | Existing `.comfyignore` excludes tests, scripts, CI, agent instructions, and root developer docs. Preflight checks runtime files and example assets remain included. | - -The old unrestricted caption write is a plausible explanation for the -1.2.0/1.3.0 verdict: a request could target a custom node's requirements -file, affecting a later dependency installation. This is an audit inference, -not an assertion that the Registry confirmed this exact chain. The prior -folder-approval proposal in PR #58 is superseded by strict media containment; -it must not be merged back into this candidate. - -Model loading and LoRA metadata remain separate existing features: registered -model paths resolve through ComfyUI, weight loading uses safe-loading modes, -and trigger/hash stores use fixed application filenames. Civitai metadata -uses a derived `.civitai.info` sidecar. The media-path rule does not mean the -pack never reads installed models or its own settings. This audit does not -claim to sandbox a local attacker who can replace server files concurrently. - -## Validation - -- 29/29 backend test files: 674 tests, all passed using the installed ComfyUI - interpreter and core video integration. The initial sandbox run prevented - dependency-cache initialization; a run with normal cache access passed. -- 461 JavaScript tests passed with the same isolation mode used by CI. -- Node validator, release preflight, and whitespace checks passed. -- An isolated CPU-only ComfyUI instance on port 8191 passed 11 live API checks: - registration, ordinary image/caption saving, absolute path rejection, - filename and caption symlink rejection, folder-route rejection cases, - rejected outside/network video previews, and a working managed video preview. -- Real browser checks verified valid and invalid Save Image card states, - serialized folder values, and chime decoding/playback after a user gesture. -- The shipped Image and Video Transform and node-tour workflows loaded with - no missing classes, overlaps, or browser exceptions. - -Local evidence remains under `_scratch/registry-*` and -`_scratch/node_screenshots/registry_save_*.png`. An older clean-install test -copy was moved out of the checkout because the mapping scanner detected its -duplicate node definitions. No scanner rule was weakened. - -## Activation remains a separate gate - -Merging these changes does not modify the published 2.0.1 archive. An -explicitly authorized release must bump both version fields, retitle the -Unreleased changelog, pass preflight, publish once, and verify the exact -version's Registry status. A successful upload or CI run is not approval. -Only `NodeVersionStatusActive` establishes availability through Manager. -Request review of that corrected artifact on issue #216 with its version id -and immutable source commit; do not request clearance for the older banned -artifacts. Obtain authorization before posting that follow-up. diff --git a/docs/workflow_review_2_1.md b/docs/workflow_review_2_1.md deleted file mode 100644 index ffe0508..0000000 --- a/docs/workflow_review_2_1.md +++ /dev/null @@ -1,88 +0,0 @@ -# Workflow review for 2.1.0 - -Reviewed the 17 public examples on 2026-09-22 for changes that should carry -across related graphs. Nine workflows were updated. - -| Example | Change | -| --- | --- | -| Krea 2 Outpaint | Describe the unpadded reference with its existing Krea text encoder; join the description with editable outpaint direction. | -| Klein 9B Outpaint | Add a Qwen3-VL source description after the existing PixaOutpaint trigger and replacement instruction. | -| MiniMax H3 Image to Video | Join a source description with the separately editable motion, camera and audio instructions. | -| MiniMax H3 First + Last Frame | Describe both references separately, retain the transition instructions, and replace the hardcoded ending timestamp with opening/final composition language. | -| LTX 2.3 Video Outpaint | Feed the first frame from the new original output to the captioner, excluding the padded bands; adjust spacing and explain the new Fixed frames control. | -| Krea 2 Studio | Connect LoRA trigger words to the prompt shared by both sampling passes. | -| Krea 2 Text to Image + LoRA Stack | Use AusBoss Save Image and save the assembled prompt as a matching text sidecar. | -| Krea 2 Prompt from Image | Retain its working caption encoder/settings; document the sampling requirement and make room for the current core widgets. | -| Image and Video Transform | Compare each result with its original source using the new outputs; explain Crop/Pad, Reset crop, Align and stitcher. | - -The text-to-image examples have no source to caption. Edit and inpaint -examples retain explicit change instructions: a description of the old scene -is not a substitute for the requested edit. The node tour, watermark remover -and Resolution Master need no generated prompt. - -## Caption checks - -Krea's saved sampling settings produced a useful description. A greedy -probe returned empty text, so Krea keeps sampling enabled and reuses its -existing encoder. H3's conditioning encoder produced punctuation with both -greedy and sampled decoding in this installation. H3 and Klein therefore -use the tested Qwen3-VL 8B INT8 caption model with a separate download row; -their own conditioning encoders remain connected to the renderer. - -The LTX caption describes one source frame. It does not observe motion over -the full clip. The H3 motion and audio instructions remain authored text. - -## Verification - -Canvas exports and API execution records are in -`_scratch/workflow_refresh/`. Full runs cover Krea Outpaint, Klein Outpaint, -Krea Prompt from Image, both H3 image-guided examples, the LoRA Stack -example and the transform example. The Studio prompt assembly and LTX -caption branches were run separately. The LoRA prompt sidecar was checked -against the displayed prompt; both H3 outputs contain an audio stream. - -After the LTX transformer and outpaint LoRA were restored, the complete -LTX example passed a fresh run with its saved settings: 97 frames at 24 fps, -1280 × 704, with source audio. The first, middle and last frames were visually -checked. The caption describes the unpadded source and the output fills the -added side bands. Execution and media checks are in `_scratch/release_ltx_*`. - -## Fixed-frame clip window - -The Clip node now exposes `fixed_frames` separately from the existing maximum -frame cap. Its five-second window was checked with 120 frames at 24 fps on a -ten-second source: real mouse drags on both handles and the selection band, -end clamping, live linked count changes, save/reload, fullscreen editor parity, -linked IN anchoring, unknown upstream values and return to free trim. Backend -checks cover exact output and audio duration after rate conversion and thinning, -overrides of Limit/Snap/OUT, and a clear error for a source that is too short. -The LTX example keeps its original free-trim defaults and documents fixed length -as an optional mode. Its enlarged Clip card and source group have no overlaps. - -A queued Integer → Clip → Save Video graph exported exactly 120 frames at -24 fps from a 2.5-second source offset. The saved video and audio streams both -measure 5.000 seconds. Clip/backend tests (62) and frontend tests (471) pass, -as do node validation and the 2.1.0 release preflight. - -## Release usability review - -A further review found that LoRA absorption skipped repeated filenames and -moved upstream rows behind the current stack. It now preserves each application -and the original order. It also checks shared MODEL and CLIP paths (including -reroutes), connected auxiliary outputs, bypassed destinations and linked stack -values before changing the graph. Loaders without a CLIP input import with -CLIP strength 0. Browser checks preserved three applications at strengths -0.2, 0.4 and 0.7, and a real click on Absorb left a shared branch unchanged. - -The transform editor’s Reset all label implied a wider reset than it performs. -It now says Reset transform, with a tooltip that names the retained settings. -A browser check confirmed that trim, Fixed frames and resize survive while -rotation and padding reset. Reset also keeps the selected preview frame; it -previously reset the frame widget without updating the timeline readout. The README now lists the Clip node’s original -output. Frontend regression checks pass (473 tests); node validation and release -preflight also pass. Review screenshots are in `_scratch/node_screenshots/`. - -Final release checks: 698 backend tests across 31 files and 473 frontend tests -pass. README local links, the 17-example count, node validation and release -preflight pass. The README reflects ComfyUI 0.37.0 / frontend 1.53.6 and the -new transform outputs, Crop/Pad controls and LoRA absorption behavior.